<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6413948643772751285</id><updated>2024-10-08T19:03:48.385-07:00</updated><category term="Multi-touch"/><category term="WPF"/><category term="C#"/><category term="C++"/><category term="3D"/><category term="Silverlight"/><category term="XAML"/><category term="windows"/><category term="DLL"/><category term="My Project"/><category term="Programing"/><category term="Tool"/><category term="Game"/><category term="Android"/><category term="Farseer"/><category term="blog"/><title type='text'>Thinking and Coding</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>60</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-3574884621270073935</id><published>2015-03-23T19:14:00.005-07:00</published><updated>2015-05-25T20:37:07.643-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Android"/><category scheme="http://www.blogger.com/atom/ns#" term="My Project"/><title type='text'>sTouch Board is now available on Google Play!</title><content type='html'>We launched&amp;nbsp;an interactive&amp;nbsp;app in &lt;b&gt;Google Play&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;https://play.google.com/store/apps/details?id=sTouch.Android.Client&amp;amp;hl=en-us&quot;&gt;https://play.google.com/store/apps/details?id=sTouch.Android.Client&amp;amp;hl=en-us&lt;/a&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjizDbzgyi_z4ZHm2nrwG69-MtlKa8i3CCyoZhmAD0guOTsT-dTvBkJ3QQH49Ro1nWZp40jq8pTPH8iLKFA4v_18t7vSvkUINegeo5lHRb3G9yp0IFnDv7Rsv8lWz6SarFvazczJeXwGuYu/s1600/150310135447.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjizDbzgyi_z4ZHm2nrwG69-MtlKa8i3CCyoZhmAD0guOTsT-dTvBkJ3QQH49Ro1nWZp40jq8pTPH8iLKFA4v_18t7vSvkUINegeo5lHRb3G9yp0IFnDv7Rsv8lWz6SarFvazczJeXwGuYu/s1600/150310135447.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
sTouch Board- Getting Started&lt;/div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;iframe allowfullscreen=&quot;&quot; class=&quot;YOUTUBE-iframe-video&quot; data-thumbnail-src=&quot;https://i.ytimg.com/vi/HiUWscPeHyA/0.jpg&quot; frameborder=&quot;0&quot; height=&quot;266&quot; src=&quot;http://www.youtube.com/embed/HiUWscPeHyA?feature=player_embedded&quot; width=&quot;320&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;sTouh Board Client&lt;/b&gt; allows users to turn their Android tablet/phone into an interactive whiteboard. With the App you can view shared content, control your presentation device, and annotate over any content.&lt;br /&gt;
&lt;br /&gt;
How To Use:&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: blue;&quot;&gt;1. Install sTouch Board Windows version&lt;/span&gt;&lt;span style=&quot;color: #073763;&quot;&gt;:&lt;/span&gt;&lt;/b&gt; The &lt;b&gt;sTouch Board Client&lt;/b&gt; App requires the Windows version of &lt;b&gt;sTouch Board&lt;/b&gt; software installed on your Windows device. You can download from here: &lt;a href=&quot;http://www.stouchtech.com/#!download/c12ug&quot;&gt;http://www.stouchtech.com/#!download/c12ug&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: blue;&quot;&gt;2. Network Environment:&lt;/span&gt;&lt;/b&gt; &lt;/span&gt;Make sure &lt;b&gt;sTouch Board&lt;/b&gt; and &lt;b&gt;sTouch Board Client&lt;/b&gt; are on the same network.&lt;br /&gt;
&lt;br /&gt;
&lt;b style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;color: blue;&quot;&gt;3. Connect to sTouch Board :&lt;/span&gt;&lt;/b&gt; Select the room you from pairing list, and click JOIN.&lt;br /&gt;
Please check software user manual for more detail:&lt;br /&gt;
&lt;a href=&quot;http://media.wix.com/ugd/4ee221_94f3d4c3b321492eabe396860db8c6cc.pdf&quot;&gt;http://media.wix.com/ugd/4ee221_94f3d4c3b321492eabe396860db8c6cc.pdf&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
We also provide interactive solutions for &lt;b&gt;School Education/Office Presentation/Home Entertainment&lt;/b&gt;, please see the following components:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1. sTouch TV:&lt;/b&gt; It is the most cost effective solution for large touch screen in the world. Easy to set up! Easy to use! You can draw, write and play on the TV.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2. sTouch Whiteboard :&lt;/b&gt; It is a low-cost solution that simply turns a traditional whiteboard or projector surface into an interactive whiteboard.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;3. sTouch Board:&lt;/b&gt; It is image-based, simple, intuitive whiteboard App available for Windows 8/Windows 7 system.&lt;br /&gt;
Features include:&lt;br /&gt;
- Drawing Tools - Color pens, highlighter pen, eraser, etc&lt;br /&gt;
- Present - Import document files or images into the app to make great presentation&lt;br /&gt;
- Sharing and Interactive - Broadcast your screen content and interact with remote devices&lt;br /&gt;
- Record - Ability to record and capture your screen&lt;br /&gt;
- Annotate - Annotate directly on the desktop screen&lt;br /&gt;
&lt;br /&gt;
For more details, please refer the link: &lt;a href=&quot;http://www.stouchtech.com/&quot;&gt;http://www.stouchtech.com/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/3574884621270073935/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2015/03/stouch-board-is-now-available-on-google.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/3574884621270073935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/3574884621270073935'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2015/03/stouch-board-is-now-available-on-google.html' title='sTouch Board is now available on Google Play!'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjizDbzgyi_z4ZHm2nrwG69-MtlKa8i3CCyoZhmAD0guOTsT-dTvBkJ3QQH49Ro1nWZp40jq8pTPH8iLKFA4v_18t7vSvkUINegeo5lHRb3G9yp0IFnDv7Rsv8lWz6SarFvazczJeXwGuYu/s72-c/150310135447.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-4289072901953095338</id><published>2011-02-09T22:51:00.000-08:00</published><updated>2011-02-10T05:51:47.627-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><title type='text'>事件的深入分析(function pointer, delegate, event, EventHandler)</title><content type='html'>&lt;div style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;Function pointer(函數指標)&lt;/b&gt;&lt;/div&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;在&lt;b&gt;C/C++&lt;/b&gt; 若要設計事件(Callback function), 可利用&lt;b&gt;function pointer&lt;/b&gt;來完成, 其詳細作法可參考&lt;a href=&quot;http://johnniebooks.blogspot.com/2010/09/callback-function.html&quot;&gt;Callback Function&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif; font-size: small;&quot;&gt;&lt;b&gt;Delegate(委託)&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;delegate&lt;/b&gt;是&lt;strong&gt;C#&lt;/strong&gt;特殊的類別, 它可以封裝一個函數, 但與一般類別不同之處,&lt;b&gt;delegate&lt;/b&gt;擁有一個簽名(&lt;b&gt;&lt;span style=&quot;background-color: #d0e0e3;&quot;&gt;可以代表函式的引數類型和回傳值類型&lt;/span&gt;&lt;/b&gt;). &lt;b&gt;delegate&lt;/b&gt;實現的功能和&lt;b&gt;C/C++&lt;/b&gt;中的函數指標十分相似.&lt;br /&gt;
&lt;br /&gt;
C/C++ :&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; void (*UpdateCallback)(double time);&lt;br /&gt;
&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif; font-size: small;&quot;&gt;C# : &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; delegate void UpateDelegate(double time);&lt;br /&gt;
&lt;br /&gt;
雖然&lt;b&gt;delegate&lt;/b&gt;類似於函式指標(function pointer), 不過還是有很多不同之處, 例如&lt;b&gt;delegate&lt;/b&gt;具有物件導向和型別安全等特性&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;delegate用法&lt;/b&gt;&lt;br /&gt;
&lt;strong&gt;delegate&lt;/strong&gt;的使用步驟如下:&lt;/div&gt;&lt;div style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;1. 宣告委派型別&amp;nbsp; &lt;/b&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;宣告一個&lt;/span&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;delegate&lt;/b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;的型別, 每個&lt;/span&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;delegate&lt;/b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;型別封裝了函數的回傳類型,引數的數目, 和引數的類型, 如下面陳述式所示&lt;/span&gt;:&lt;br /&gt;
&lt;pre class=&quot;C#&quot; name=&quot;code&quot;&gt;delegate void MessageDelegate(string str);
&lt;/pre&gt;&lt;div style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/div&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;2. 定義一個符合委派型別的簽名方法, 可為 instance method 或 static method&lt;/b&gt;&lt;br /&gt;
&lt;pre class=&quot;C#&quot; name=&quot;code&quot;&gt;public static void HelloFun(string str)
{
   Console.WriteLine(&quot;  Hello, {0}!&quot;, str);
}
public static void GoodbyeFun (string str)
{
   Console.WriteLine(&quot;  Goodbye, {0}!&quot;, str);
}
&lt;/pre&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;3. 建立委派物件, 並指定委派方法&lt;/b&gt;&lt;br /&gt;
&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;delegate&lt;/b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;宣告後, 必須再將它實體化才能使用(和一般類別的使用方式一樣, 需先將物件實體化), 並指定所代表的函式, 但不需傳入引數, 如下面範例所示&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;C#&quot; name=&quot;code&quot;&gt;static void Main(string[] args)
{
   MessageDelegate msDelegate = new MessageDelegate(HelloFun);
}
&lt;/pre&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;b&gt;delegate&lt;/b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;同時也支援&lt;span style=&quot;background-color: #9fc5e8;&quot;&gt;&lt;strong&gt;多點傳送(+=, -=)&lt;span style=&quot;background-color: white;&quot;&gt;,&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt; 因為繼承自&lt;a href=&quot;http://system.multicastdelegate/&quot;&gt;System.MulticastDelegate&lt;/a&gt;類別, &lt;/span&gt;你可以使用&lt;b&gt;+= 運算子&lt;/b&gt;將多個方法綁定到同一個&lt;b&gt;delegate&lt;/b&gt;, 當呼叫這個&lt;b&gt;delegate&lt;/b&gt;的時候, 將依次呼叫其所綁定的方法. 當然你也可以使用&lt;b&gt; - = 運算子 &lt;/b&gt;將某個委派參考從委派清單中移除.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;pre class=&quot;C#&quot; name=&quot;code&quot;&gt;MessageDelegate msDelegate;
 msDelegate = new MessageDelegate(HelloFun);
 msDelegate += new MessageDelegate(GoodbyeFun);
 msDelegate -= new MessageDelegate(HelloFun);
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;4. 透過委派物件執行委派方法&lt;/b&gt;&lt;br /&gt;
如下所示:&lt;br /&gt;
&lt;pre class=&quot;C#&quot; name=&quot;code&quot;&gt;msDelegate(&quot;Peter&quot;); //等同msDelegate.invoke(&quot;Peter&quot;);
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;event&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;event&lt;/b&gt;的出現,是要避免使用&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;delegate&lt;/b&gt;可能會破壞物件封裝性的問題,主要有下面兩&lt;/span&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;點:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;1.&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;delegate &lt;/b&gt;可以隨意進行賦值操作, 若不小心使用將會移除所有委派&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;2.&amp;nbsp;&amp;nbsp;&amp;nbsp; 為了讓&lt;strong&gt;delegate&lt;/strong&gt;可以綁定特定的方法, 宣告時必須定義成&lt;b&gt;public&lt;/b&gt;屬性, 但也因此破壞掉物件的封裝性, 因為類別的內外都可以呼叫&lt;strong&gt;delegate&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
考慮下面例子:&lt;br /&gt;
&lt;pre class=&quot;C#&quot; name=&quot;code&quot;&gt;public class ButtonControl
{
        public delegate void ClickDelgate(object sender, EventArgs e);        
        public ClickDelgate ClickEvent; 
        public void OnFire(EventArgs e)
        {
            ClickEvent(this, e);
        }
}

static public void TexboxUpdate(object sender, EventArgs e)
{
     Console.WriteLine(&quot;Texbox update by button click&quot;);
 }

 static public void LabelUpdate(object sender, EventArgs e)
 {
      Console.WriteLine(&quot;Label update by button click&quot;);
 }

static void Main(string[] args)
{
ButtonControl btnCtrl = new ButtonControl();
      btnCtrl.ClickEvent = new ButtonControl.ClickDelgate(TexboxUpdate);
      btnCtrl.ClickEvent += new ButtonControl.ClickDelgate(LabelUpdate);
btnCtrl.ClickEvent = null;  //這將會移除所有委派
      btnCtrl.ClickEvent(null, new EventArgs()); //不應該讓使用者可以呼叫
}
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
而就&lt;a href=&quot;http://zh.wikipedia.org/zh-tw/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F&quot;&gt;觀察者模式&lt;/a&gt;來說, 也應避免下面這些情況:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;對於客戶端(觀察者), 應該只適合透過註冊/取消來操作自己對應的事件, 不應該隨意進行的賦值操作, 如果不小心將發佈者的&lt;b&gt;delegate&lt;/b&gt;類別直接賦值&lt;b&gt;null&lt;/b&gt;, 將會取消掉發佈者所有的通知列表&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;發佈事件的通知應該由發佈者來觸發, 不應該讓客戶端可以呼叫&lt;/li&gt;
&lt;/ul&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;因此&lt;strong&gt;C#&lt;/strong&gt;利用&lt;b&gt;event&lt;/b&gt;來封裝&lt;b&gt;delegate&lt;/b&gt;類型的變數, 所以在類別的外部, 使用者只能透過註冊&lt;b&gt;“+=”&lt;/b&gt;和取消&lt;b&gt;“-=”&lt;/b&gt; 來作事件的操作.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Event使用範例&lt;/b&gt;&lt;br /&gt;
將上述範例中,&lt;span style=&quot;background-color: white;&quot;&gt; &lt;span style=&quot;color: blue;&quot;&gt;public&lt;/span&gt;&lt;/span&gt; ClickDelgate ClickEvent 加上 &lt;b&gt;&lt;span style=&quot;color: blue;&quot;&gt;event&lt;/span&gt;&lt;/b&gt;修飾字&lt;br /&gt;
&lt;pre class=&quot;C#&quot; name=&quot;code&quot;&gt;public class ButtonControl
{
        public delegate void ClickDelgate(object sender, EventArgs e);        
        public event ClickDelgate ClickEvent; 
        public void OnFire(EventArgs e)  
        {
            if (ClickEvent != null)
                ClickEvent(this, e);
        }
}

static void Main(string[] args)
{
   ButtonControl btnCtrl = new ButtonControl();

   //只能使用+=,-= 來對事件操作
   btnCtrl.ClickEvent += new ButtonControl.ClickDelgate(TexboxUpdate);
   btnCtrl.ClickEvent += new ButtonControl.ClickDelgate(LabelUpdate);
}
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;EventHandler&lt;/b&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;雖然 &lt;/span&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;C#&lt;/b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt; 語言允許&lt;/span&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;event&lt;/b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;使用任一種&lt;/span&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;delegate&lt;/b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;型別,但是 &lt;/span&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;.NET Framework &lt;/b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;對於使用於&lt;/span&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;event&lt;/b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;的&lt;/span&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;delegate&lt;/b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;型別有更嚴格的規範, 因此另外定義出一個適當的&lt;/span&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;delegate&lt;/b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;型別&lt;/span&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;EventHandler&lt;/b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;, 語法如下:&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;C#&quot; name=&quot;code&quot;&gt;public delegate void EventHandler(object sender, EventArgs e);
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;EventHandler &lt;/b&gt;為預先定義的&lt;b&gt;delegate&lt;/b&gt;, &lt;b&gt;EventHandler&lt;/b&gt;會定義一個&lt;span style=&quot;background-color: white;&quot;&gt;沒有傳回值的方法&lt;/span&gt;, 方法第一個參數的型別為 &lt;b&gt;object&lt;/b&gt;, 表示引發事件的執行個體(如果是button1的click事件, 則&lt;b&gt;sender&lt;/b&gt;就是button1）, 而第二個參數的型別為&lt;b&gt;EventArgs&lt;/b&gt;, 表示封裝事件的額外資訊.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;EventHandler使用範例&lt;/b&gt;&lt;br /&gt;
&lt;pre class=&quot;C#&quot; name=&quot;code&quot;&gt;public class ButtonControl
 {
        //利用EventHandler取代delegate void EventHandler(object sender, EventArgs e)
        public event EventHandler ClickEventHandler;  
        public void OnClick()
        {
            if (ClickEventHandler != null)
            {
                ClickEventHandler(this, new EventArgs());
            }           
        }
 }
&lt;/pre&gt;&lt;br /&gt;
&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;自訂EventArgs&lt;/b&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;在&lt;/span&gt;&lt;b style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;.NET Framework 2.0&lt;/b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;時引進&lt;b&gt;EventHandler&lt;/b&gt;泛型版本，即&lt;b&gt; EventHandler&lt;/b&gt;&amp;lt;T&amp;gt;也就是如果你要自訂的 &lt;b&gt;EventArgs &lt;/b&gt;類別, 可以參考下面範例:&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;C#&quot; name=&quot;code&quot;&gt;public event EventHandler&amp;lt;customeventargs&amp;gt; RaiseCustomEvent;

public class CustomEventArgs : EventArgs
{
    public CustomEventArgs(string s)
    {
        msg = s;
    }
    private string msg;
    public string Message
    {
        get { return msg; }
    } 
}
&lt;/pre&gt;&lt;br /&gt;
參考資料:&lt;br /&gt;
&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/w369ty8x%28VS.80%29.aspx&quot;&gt;發行符合 .NET Framework 方針的事件&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/aa288459%28VS.71%29.aspx&quot;&gt;委派教學課程&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/aa288460%28VS.71%29.aspx&quot;&gt;事件教學課程&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.cnblogs.com/cuihongyu3503319/archive/2007/03/06/665262.html&quot;&gt;函數指標的進化論(下)&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://%e6%88%91%e5%b0%8d.net%e4%b8%addelegate%e5%92%8cevent%e5%8d%80%e5%88%ab%e7%9a%84%e7%90%86%e8%a7%a3/&quot;&gt;我對.NET中delegate和event區别的理解&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.cnblogs.com/miaomiaoga/articles/56186.html&quot;&gt;談談委派 (Delegate)&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://huan-lin.blogspot.com/2009/01/delegate-revisited-csharp-1-to-2-to-3.html&quot;&gt;C# 筆記：重訪委派－從 C# 1.0 到 2.0 到 3.0&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/4289072901953095338/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2011/02/function-pointer-delegate-event.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/4289072901953095338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/4289072901953095338'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2011/02/function-pointer-delegate-event.html' title='事件的深入分析(function pointer, delegate, event, EventHandler)'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-547719883946950122</id><published>2010-12-31T00:11:00.000-08:00</published><updated>2010-12-31T00:20:51.510-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><title type='text'>WPF - Style使用</title><content type='html'>&lt;b&gt;Style(樣式)&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Style&lt;/b&gt;主要就是透過屬性(&lt;b&gt;Property&lt;/b&gt;)去自訂控制項的外觀, 尤其當我們需要相同的屬性套用在多個控制項時, &lt;b&gt;Style&lt;/b&gt;會很方便.&lt;br /&gt;
&lt;br /&gt;
比方在&lt;b&gt;UI&lt;/b&gt;設計時, 常會讓&lt;b&gt;UI&lt;/b&gt;具有某些相同的&lt;b&gt;Style&lt;/b&gt;,例如:背景顏色,字型,控制項的顏色…等等.&lt;br /&gt;
&lt;br /&gt;
使用&lt;b&gt;Style&lt;/b&gt;的好處如下:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;可以方便使用者將一組屬性值(顏色,尺寸,動畫, 觸發方式等)套用到多個控制項的方式,這樣一來, 程式碼將變得簡潔.&lt;/li&gt;
&lt;li&gt;可集中在同一個地方作管理(ex: 資源&lt;b&gt; Resource&lt;/b&gt;), 好處如果以後想改變這些屬性, 只要在同一個地方更新即可&lt;/li&gt;
&lt;/ul&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;例如下面範例中, 有一個影音播放程式,如圖1所示, 其中&lt;b&gt;UI&lt;/b&gt;上有三個外觀相同的按鈕, 在這程式碼當中, 如圖2所示, 如果不套用&lt;b&gt;Style&lt;/b&gt;的話, 我們必需要將每一個控制項都設定一次相同的屬性, 這樣, 程式碼將會有很多重覆的部分, 而且, 萬一以後要變更其中一個屬性, 將要修改到很多地方 &lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVmN2elPRCHXFF1bz8uModI5XDrEUKlGntcPm6s09dS7OHGqjAOm6IyM_R5C2a3oJwJI_i_AnDq7_b5FNXrylKgvelyAKZ05YD5J1SCXJxwuizPZ75PO1YzAue2ipbAY5WxIuvmoEC1C1N/s1600/style.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVmN2elPRCHXFF1bz8uModI5XDrEUKlGntcPm6s09dS7OHGqjAOm6IyM_R5C2a3oJwJI_i_AnDq7_b5FNXrylKgvelyAKZ05YD5J1SCXJxwuizPZ75PO1YzAue2ipbAY5WxIuvmoEC1C1N/s1600/style.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;&amp;nbsp; &lt;/b&gt;[圖1]具有一些相同屬性的&lt;b&gt;Button&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxKqqiRQv5215hxps52aGaVOA09ISZA7sIbY-bLlfcImicPyQQjDLbguUoG-tAF7ykjjOAK9-eom68hNxqIzZfZ2xgpEJxwiZ2XRpRkN_hoYmsP8Q4ieU_IpSrQ-qUU-YPBfP0FhQwMLBN/s1600/nostyle.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxKqqiRQv5215hxps52aGaVOA09ISZA7sIbY-bLlfcImicPyQQjDLbguUoG-tAF7ykjjOAK9-eom68hNxqIzZfZ2xgpEJxwiZ2XRpRkN_hoYmsP8Q4ieU_IpSrQ-qUU-YPBfP0FhQwMLBN/s1600/nostyle.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [圖2] 沒有套用&lt;b&gt;Style&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;下面的範例中, 我們利用&lt;b&gt;Style&lt;/b&gt;將上述程式碼中相同屬性抽離出來(&lt;b&gt;Style&lt;/b&gt;用&lt;b&gt;Setter&lt;/b&gt;組成的集合來設定目標屬性, 而每個&lt;b&gt;Setter&lt;/b&gt;是由依存屬性和設定值組成), 並集中在&lt;b&gt;Resource&lt;/b&gt;中. 程式碼將變得簡潔, 管理上也變的更方便&lt;b&gt;,&lt;/b&gt; 如圖3所示.&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRBuXZfjPMIJh5e8D-XEBjyLZ7jiVJmKn3Zj_cCfWZTPM7PDRAPCGGLU159YDePMTZ0YDqrXa5zI5T7LHFEU33MQhXKeC75rzB5-K32n5MLpyWQ5jVWFmuvN-iP5RoXoNwBslNg3FuhyphenhyphenB5/s1600/usestyle.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRBuXZfjPMIJh5e8D-XEBjyLZ7jiVJmKn3Zj_cCfWZTPM7PDRAPCGGLU159YDePMTZ0YDqrXa5zI5T7LHFEU33MQhXKeC75rzB5-K32n5MLpyWQ5jVWFmuvN-iP5RoXoNwBslNg3FuhyphenhyphenB5/s1600/usestyle.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [圖3] 套用&lt;b&gt;Style&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;b&gt;Style的共享與限定&lt;/b&gt;&lt;br /&gt;
你也可以將&lt;b&gt;Style&lt;/b&gt;套用在不同的控制項上,如下所示:&lt;br /&gt;
&lt;pre class=&quot;xml&quot; name=&quot;code&quot;&gt;&amp;lt;Style x:Key=&quot;controlStyle&quot;&amp;gt;
  &amp;lt;Setter Property=&quot;Control.Height&quot; Value=&quot;30&quot;/&amp;gt;
  &amp;lt;Setter Property=&quot;Control.Width&quot; Value=&quot;75&quot;/&amp;gt;
  &amp;lt;Setter Property=&quot;Control.Margin&quot; Value=&quot;10&quot;/&amp;gt;
  &amp;lt;Setter Property=&quot;Control.Background&quot; 
                    Value=&quot;{StaticResource btnBackground}&quot;/&amp;gt;
&amp;lt;/Style&amp;gt;

&amp;lt;!-- Style套用在不同的控制項上--&amp;gt;
&amp;lt;Button x:Name=&quot;btnPlay&quot; Grid.Column=&quot;0&quot;
           Style=&quot;{StaticResource controlStyle}&quot;
           Content=&quot;Play&quot; Click=&quot;btnPlay_Click&quot;&amp;gt;
&amp;lt;/Button&amp;gt;

&amp;lt;Label Grid.Column=&quot;1&quot;
          Style=&quot;{StaticResource controlStyle}&quot;
          Content=&quot;Text Block&quot;/&amp;gt;
            
&amp;lt;Border Grid.Column=&quot;2&quot;
           Style=&quot;{StaticResource controlStyle}&quot;/&amp;gt;

&lt;/pre&gt;&lt;br /&gt;
或限定此&lt;b&gt;Style&lt;/b&gt;只能給特定的控制項使用, 可用&lt;b&gt;TargetType&lt;/b&gt;屬性指定, 例如你希望只有&lt;b&gt;Button&lt;/b&gt;可套用此&lt;b&gt;Style&lt;/b&gt;, 可寫成:&lt;br /&gt;
&lt;pre class=&quot;xml&quot; name=&quot;code&quot;&gt;&amp;lt;Style x:Key=&quot;btnStyle&quot; TargetType=&quot;{x:Type Button}&quot;&amp;gt;
     &amp;lt;Setter Property=&quot;Height&quot; Value=&quot;30&quot;/&amp;gt;
     &amp;lt;Setter Property=&quot;Width&quot; Value=&quot;75&quot;/&amp;gt;
     &amp;lt;Setter Property=&quot;Margin&quot; Value=&quot;10&quot;/&amp;gt;
     &amp;lt;Setter Property=&quot;Background&quot; 
                Value=&quot;{StaticResource btnBackground}&quot;/&amp;gt;
&amp;lt;/Style&amp;gt;

&lt;/pre&gt;若此&lt;b&gt;Syle&lt;/b&gt;套用在非&lt;b&gt;Button&lt;/b&gt;的控制項上, 將會產生編譯錯誤&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Style繼承&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Style&lt;/b&gt;之間可以互相繼承, 如果要這樣做, 您可以使用一個樣式做為基礎來建立新樣式, 並利用&lt;b&gt;BasedOn&lt;/b&gt;屬性來繼承 &lt;br /&gt;
&lt;pre class=&quot;xml&quot; name=&quot;code&quot;&gt;&amp;lt;Style x:Key=&quot;btnStyleWithBold&quot; 
          BasedOn=&quot;{StaticResource btnStyle}&quot;
   &amp;lt;Setter Property=&quot;Button.FontWeight&quot; Value= &quot;Bold&quot;/&amp;gt;
&amp;lt;/Style&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
另外, &lt;b&gt;Style&lt;/b&gt;除了可用來設定控制項的屬性(&lt;b&gt;Property&lt;/b&gt;)之外, 還可以運用在下列幾個地方&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;設定觸發方式(Trigger)&lt;/li&gt;
&lt;li&gt;設定動畫(Animation)&lt;/li&gt;
&lt;li&gt;設定樣板(Template)&lt;/li&gt;
&lt;/ul&gt;相關範例, 可參考: &lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/ms745683.aspx&quot;&gt;MSDN-設定樣式與範本&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/547719883946950122/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2010/12/wpf-style.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/547719883946950122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/547719883946950122'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2010/12/wpf-style.html' title='WPF - Style使用'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVmN2elPRCHXFF1bz8uModI5XDrEUKlGntcPm6s09dS7OHGqjAOm6IyM_R5C2a3oJwJI_i_AnDq7_b5FNXrylKgvelyAKZ05YD5J1SCXJxwuizPZ75PO1YzAue2ipbAY5WxIuvmoEC1C1N/s72-c/style.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-1340346920825507736</id><published>2010-12-14T03:01:00.000-08:00</published><updated>2010-12-14T05:55:49.660-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Multi-touch"/><title type='text'>Touch UI 設計準則</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;b&gt;Touch UI&lt;/b&gt; 的操作行為其實和傳統使用滑鼠或鍵盤的操作有些出入, 因此, 在開發觸控軟體時, 有部分的&lt;b&gt;UI&lt;/b&gt;設計和操作都需重新設計或調整. 而好的&lt;b&gt;UI&lt;/b&gt;設計通常會跟&lt;a href=&quot;http://en.wikipedia.org/wiki/User_experience_design&quot;&gt;&lt;b&gt;使用者經驗設計&lt;/b&gt;&lt;/a&gt;(&lt;b&gt;User Experience Design &lt;/b&gt;)有很大的關聯. 在這篇文章中, 我會整理出&lt;b&gt;Windows上&lt;/b&gt;開發觸控軟體需要注意的事項, 提供給大家參考.&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;b&gt;1.&amp;nbsp;&amp;nbsp;&amp;nbsp; 控制元件要夠大&lt;/b&gt; – 因為觸控&lt;b&gt;UI&lt;/b&gt;操作方式不是透過是滑鼠游標, 而是利用手指操控, 所以控制元件的大小不能太小, 否則會很難操作, 一般最好能符合人的手指大小, 微軟提出理想尺寸最少要在&lt;span style=&quot;background-color: yellow;&quot;&gt;40*40(Pixel)&lt;/span&gt;以上&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitYhYUR1NrCh_a5e-i6Rv-elm56gFvLlo299xDqb00OQEqkHP9fkB_eun8RdCdJQJ4KugTC-VDx_wvzV0VnU1CAnzAxik_OXjfQh6z2qGBsISxCMODxk0Umfbt300pS3zIuRbRB4MTqBcu/s1600/1.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitYhYUR1NrCh_a5e-i6Rv-elm56gFvLlo299xDqb00OQEqkHP9fkB_eun8RdCdJQJ4KugTC-VDx_wvzV0VnU1CAnzAxik_OXjfQh6z2qGBsISxCMODxk0Umfbt300pS3zIuRbRB4MTqBcu/s1600/1.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; [圖1]- 觸控元件的合理大小 &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;MsoListParagraph&quot; style=&quot;font-family: Arial,Helvetica,sans-serif; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;2.&lt;span style=&quot;font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;控制元件之間的間距要夠大&lt;/b&gt; &lt;span lang=&quot;EN-US&quot;&gt;–&lt;/span&gt;如果觸控&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;UI&lt;/span&gt;&lt;/b&gt;元件的間距太小&lt;span lang=&quot;EN-US&quot;&gt;,&lt;/span&gt;容易造成不小心觸控到其它控制元件的問題&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;所以元件之間的距離要夠大&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;微軟建議這範圍至少要&lt;span lang=&quot;EN-US&quot;&gt; &lt;span style=&quot;background-color: yellow;&quot;&gt;5 Pixel&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: white;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;background-color: white; clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;background-color: white; clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi_6X0qiHiDwuu6Mprv3fHzthIuL9oYLAP9L0wWpcVG9uyl3lY-OmO2U4aRK_VhdJ11XgVhFDvWJIv99_t0gO0bRb34n5-rh5EzXlpTSjLxCLoVM0lxk5z5UrK81w4REbwWKmg337u-13u/s1600/2.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi_6X0qiHiDwuu6Mprv3fHzthIuL9oYLAP9L0wWpcVG9uyl3lY-OmO2U4aRK_VhdJ11XgVhFDvWJIv99_t0gO0bRb34n5-rh5EzXlpTSjLxCLoVM0lxk5z5UrK81w4REbwWKmg337u-13u/s1600/2.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&amp;nbsp;&amp;nbsp; [圖2] - 觸控元件的間距&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;3.&amp;nbsp; 不能要求精準控制&lt;/b&gt;- 由於觸控不適合作細微的操作, 所以最好不要把需要精準控制的應用軟體設計成觸控&lt;b&gt;UI&lt;/b&gt;, 例如繪圖或建模等軟體&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;4.&amp;nbsp;&amp;nbsp; &lt;/b&gt;&lt;b&gt;適當地調整元件位置 &lt;/b&gt;– 有些觸控技術在某些區域容易出現誤判, 例如光學觸控的右上角邊緣, 就是容易發生誤判的區域, 所以在設計觸控&lt;b&gt;UI&lt;/b&gt;時, 要避免將元件放在容易誤判的區域&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;5.&amp;nbsp;&amp;nbsp; 不要有太多手部點選的動作&lt;/b&gt; – 一般會把觸控&lt;b&gt;UI&lt;/b&gt;設計成一個動作就立即反應, 這樣可以使操作變得簡單直覺也可減少手部動作, 所以如圖3的下拉式選單的操作(需要一層一層的選擇), 就不適合利用觸控作操作&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpjXjzwezh8-MaAKwZ12bIuVPCoLFaff7SXyR2TUyaAmFGbFEgnnJ2Jd0cp4gB06VxfdXSe_TzIzik2lksEm-FkybPx1jxcm-3XRlTbNdpThNdLks1Sd89bhNbj5OD21vQjpZ2JplB3KC8/s1600/3.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;251&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpjXjzwezh8-MaAKwZ12bIuVPCoLFaff7SXyR2TUyaAmFGbFEgnnJ2Jd0cp4gB06VxfdXSe_TzIzik2lksEm-FkybPx1jxcm-3XRlTbNdpThNdLks1Sd89bhNbj5OD21vQjpZ2JplB3KC8/s400/3.jpg&quot; width=&quot;400&quot; /&gt;&amp;nbsp;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; font-family: Arial,Helvetica,sans-serif; text-align: center;&quot;&gt;[圖3 ]- 下拉式選單&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: justify;&quot;&gt;&lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;6. 不要有Hover功能&lt;/b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt; – 利用滑鼠控制的&lt;/span&gt;&lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;UI&lt;/b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;, 常會利用&lt;/span&gt;&lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;Hover&lt;/b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;作一些&lt;/span&gt;&lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;highlight&lt;/b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;或提示等功能, 但觸控&lt;/span&gt;&lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;UI&lt;/b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;上最好不要有&lt;/span&gt;&lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;hover&lt;/b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;行為, 因為不可能讓使用者把手指浮在半空中作操作. 如果真的要有這樣的行為, 我覺得可以在&lt;/span&gt;&lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;mouse down &amp;amp; mouse move&lt;/b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;時發生&lt;/span&gt;&lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;hover&lt;/b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;, 然後等&lt;/span&gt;&lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;mouse up&lt;/b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;時, 在發生&lt;/span&gt;&lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;click&lt;/b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;.&lt;/span&gt; &lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; font-family: Arial,Helvetica,sans-serif; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;7.&amp;nbsp;&amp;nbsp; 使用直覺手勢&lt;/b&gt; – 觸控&lt;b&gt;UI&lt;/b&gt;在設計時, 最好能使用一些使用者常用和直覺的手勢.&lt;br /&gt;
例如下面是大家常見的手勢:&lt;br /&gt;
&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; font-family: Arial,Helvetica,sans-serif; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 平移:&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQFIDinSBfcKkf_mhN9QqzdzNfstpsNgFQDS2S2Aq3-2Vm35A1qPPBslLa8W0NhISHLHtJb0Rk8dRLnFCSW_z7dQzCTCk6RwQA_jSQfX6w4WFn4TMWR4lCrvOVzG4rFs0IhFdtnMxyGuqW/s1600/pan.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;167&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQFIDinSBfcKkf_mhN9QqzdzNfstpsNgFQDS2S2Aq3-2Vm35A1qPPBslLa8W0NhISHLHtJb0Rk8dRLnFCSW_z7dQzCTCk6RwQA_jSQfX6w4WFn4TMWR4lCrvOVzG4rFs0IhFdtnMxyGuqW/s320/pan.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [圖4] - 平移手勢(出自MSDN)&lt;br /&gt;
&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 放大, 縮小 :&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyWfpVH1GjzNa8BmIPECysev8BF82sajxOizhw1sgUjrZPvfnjVbFePczLacrcjG_m_qgMH4sKEdxKpWP802IPaG_N7hp_FE_x3d6EYs1qniqIDBV8s6lopfqa8i22wjYZ88LUeZ3IFCe0/s1600/zoom.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;216&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyWfpVH1GjzNa8BmIPECysev8BF82sajxOizhw1sgUjrZPvfnjVbFePczLacrcjG_m_qgMH4sKEdxKpWP802IPaG_N7hp_FE_x3d6EYs1qniqIDBV8s6lopfqa8i22wjYZ88LUeZ3IFCe0/s320/zoom.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; [圖5]- 縮放手勢 &lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;(出自MSDN)&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br /&gt;
旋轉:&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZtlIf6VFvKe0vqABp0hfn3RkiDhN_VFKMGHemqr9zhF-znu4_t5TcIZQGrz96WpOoCvyjvcAUPDLlNRug5gIhRLGkx7ZZ6LazBL9nbU9dPBq9pgNqhdEH4m-HAlzZpf_ToHCcf6dPuWXG/s1600/rotate.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZtlIf6VFvKe0vqABp0hfn3RkiDhN_VFKMGHemqr9zhF-znu4_t5TcIZQGrz96WpOoCvyjvcAUPDLlNRug5gIhRLGkx7ZZ6LazBL9nbU9dPBq9pgNqhdEH4m-HAlzZpf_ToHCcf6dPuWXG/s1600/rotate.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [圖6] - 旋轉手勢 &lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;(出自MSDN)&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; font-family: Arial,Helvetica,sans-serif; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;7.&amp;nbsp;&amp;nbsp; &lt;/b&gt;&lt;b&gt;加上物理行為 &lt;/b&gt;– 由於觸控是一種直覺和自然的動作, 所以可以在觸控操作中加上一些速度, 碰撞, 力量等物理反應, 讓你的&lt;b&gt;touch&lt;/b&gt;介面, 更符合&lt;b&gt;Natural UI&lt;/b&gt;的概念.下面的影片中, Demo一個我寫的&lt;b&gt;Touch Scroll UI&lt;/b&gt;(它會根據手撥動的速度快慢, 而產生不同物理反應)&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;iframe allowfullscreen=&#39;allowfullscreen&#39; webkitallowfullscreen=&#39;webkitallowfullscreen&#39; mozallowfullscreen=&#39;mozallowfullscreen&#39; width=&#39;320&#39; height=&#39;266&#39; src=&#39;https://www.youtube.com/embed/Wxlb-XDfR80?feature=player_embedded&#39; frameborder=&#39;0&#39;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; font-family: Arial,Helvetica,sans-serif; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;&amp;nbsp;8. 動作要流暢 &lt;/b&gt;–觸控&lt;b&gt;UI&lt;/b&gt;最好能提供順暢和反應靈敏的視覺反饋，例如使用旋轉手勢時，畫面的物件也要能同時作動, 不要讓使用者操作時有卡住的感覺&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: white; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;參考文章:&lt;/b&gt; &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/cc872774.aspx&quot;&gt;Touch(MSDN) &lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/1340346920825507736/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2010/12/touch-ui-%E8%A8%AD%E8%A8%88%E6%BA%96%E5%89%87.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/1340346920825507736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/1340346920825507736'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2010/12/touch-ui-%E8%A8%AD%E8%A8%88%E6%BA%96%E5%89%87.html' title='Touch UI 設計準則'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitYhYUR1NrCh_a5e-i6Rv-elm56gFvLlo299xDqb00OQEqkHP9fkB_eun8RdCdJQJ4KugTC-VDx_wvzV0VnU1CAnzAxik_OXjfQh6z2qGBsISxCMODxk0Umfbt300pS3zIuRbRB4MTqBcu/s72-c/1.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-3832217580759991806</id><published>2010-12-09T18:58:00.000-08:00</published><updated>2010-12-09T19:10:23.012-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="DLL"/><title type='text'>DLL的製作和使用</title><content type='html'>&lt;span style=&quot;background-color: yellow;&quot;&gt;&lt;/span&gt;在程式開發上, 常會將自己寫好的共用函式或共用類別編譯成&lt;b&gt;DLL&lt;/b&gt;, 這樣除了可以省記憶體空間外, 也可達到模組化方便讓其他程式共用, 這邊寫了一篇文章來介紹&lt;b&gt;DLL&lt;/b&gt;建立的流程，主要分成兩個重點：&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1.&amp;nbsp;&amp;nbsp;&amp;nbsp; DLL建立的步驟&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt; 如何建立&lt;b&gt;DLL&lt;/b&gt;檔(以C3DMath.dll為例)&lt;/li&gt;
&lt;li&gt;如何引用別人的lib檔和h檔(以MainDLLTest.exe為例)&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;b&gt;2.&amp;nbsp;&amp;nbsp;&amp;nbsp; 編譯環境的設定&lt;/b&gt;&lt;br /&gt;
在&lt;b&gt;VC&lt;/b&gt;中可以利用一些巨集指令來設定編譯環境，其優點有:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;方便管理檔案&lt;/li&gt;
&lt;li&gt;省去人工複製的時間(可以少掉複製一些h檔、 dll檔和lib檔的時間)&lt;/li&gt;
&lt;li&gt;將來可用在Auto build機制上&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;DLL建立的步驟&lt;/b&gt;-&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: black; font-family: Arial,Helvetica,sans-serif;&quot;&gt;1.&amp;nbsp;&amp;nbsp;&amp;nbsp; 建立&lt;b&gt;C3DMaths DLL&lt;/b&gt;專案：&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;開啟&lt;b&gt;VC&lt;/b&gt;點選&lt;b&gt;File &lt;/b&gt;--&amp;gt;&lt;b&gt;New&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;Project&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;--&amp;gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;b&gt;Win32 Console Application&lt;/b&gt;，然後在&lt;b&gt;Name&lt;/b&gt;的欄位輸入專案的名稱&lt;/span&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyRtYTLwJYNxHcqGD6647zfGSr4y2KggMSAsg4FjP6iebNuFH_kTkZ-SOz2NNpPCqgB2cykt_9OM1MwkbIJCnlcK3THO14kOoCu0oRIRxgahTcMZnBQmtKZRPFL9vPoozR8jg7uviIIx-7/s1600/1.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyRtYTLwJYNxHcqGD6647zfGSr4y2KggMSAsg4FjP6iebNuFH_kTkZ-SOz2NNpPCqgB2cykt_9OM1MwkbIJCnlcK3THO14kOoCu0oRIRxgahTcMZnBQmtKZRPFL9vPoozR8jg7uviIIx-7/s1600/1.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;2.&amp;nbsp;&amp;nbsp; &amp;nbsp;點選Next&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3XoIfo9nQTy5FevkJwcT9QhQVJeresR_o281_2flKiNQemJ2CrH-htwVYlZ0fbI_otFZWGniowPS6yKXXtxmaCpoXctC4ZtkAdC9NxDHdhtKlcWeWdu0MCv7vJZUhIEEIZP8yopXGrNtC/s1600/2.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3XoIfo9nQTy5FevkJwcT9QhQVJeresR_o281_2flKiNQemJ2CrH-htwVYlZ0fbI_otFZWGniowPS6yKXXtxmaCpoXctC4ZtkAdC9NxDHdhtKlcWeWdu0MCv7vJZUhIEEIZP8yopXGrNtC/s1600/2.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
3.&amp;nbsp;&amp;nbsp;&amp;nbsp; 選擇&lt;b&gt;DLL&lt;/b&gt;，然後按&lt;b&gt;Finish&lt;/b&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGIPHYOR8GTV2GGPzsrAfHq8faDaHVIvmqh7fMHV0_GAdiwenGLQQOjxUxE2al6XiXGIU3CgbHzZyISYX8H-QjMun-47Iy5GN8hbfgu_WXiXWJN_PT5zLhO6G5a2VvITBqcOUfCIJenl7F/s1600/4.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGIPHYOR8GTV2GGPzsrAfHq8faDaHVIvmqh7fMHV0_GAdiwenGLQQOjxUxE2al6XiXGIU3CgbHzZyISYX8H-QjMun-47Iy5GN8hbfgu_WXiXWJN_PT5zLhO6G5a2VvITBqcOUfCIJenl7F/s1600/4.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
4.&amp;nbsp;&amp;nbsp; &amp;nbsp;產生一個標頭檔(&lt;b&gt;C3DMath.h&lt;/b&gt;), 並加入下面這段巨集指令, 如下所示:&lt;br /&gt;
&lt;pre class=&quot;c++&quot; name=&quot;code&quot;&gt;#ifdef  API_BUILD_DLL
 #define C3DMATHS_CLASS __declspec(dllexport)
#else
 #define C3DMATHS_CLASS __declspec(dllimport)
#endif
&lt;/pre&gt;&lt;br /&gt;
&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;上面這段巨集的意思是, 如果定義了&lt;b&gt;API_BUILD_DLL &lt;/b&gt;編譯時就把字串 &lt;b&gt;C3DMATHS_CLASS&lt;/b&gt;換成_&lt;b&gt;_declspec(dllexport)&lt;/b&gt;, 否則, 就換成&lt;b&gt; __declspec(dllimport)&lt;/b&gt;, 因為&lt;b&gt;C3DMath.h &lt;/b&gt;通常會用在兩個地方: &lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;&lt;span style=&quot;background-color: white;&quot;&gt;(1)產生 &lt;b&gt;DLL&lt;/b&gt;的專案: &lt;/span&gt;需要匯出 &lt;b&gt;DLL &lt;/b&gt;的資料、函式、類別或類別成員函式,因此要使用&lt;b style=&quot;background-color: white;&quot;&gt;__declspec(dllexport) &lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;background-color: white; font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;&lt;span style=&quot;background-color: white;&quot;&gt;(2)使用 &lt;b&gt;DLL &lt;/b&gt;的專案(例如exe檔): &lt;/span&gt;此時需要匯入DLL 的資料、函式、類別或類別成員函式, 所以要用&lt;b&gt; __declspec(dllimpor&lt;/b&gt;&lt;b&gt;t)&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;5.&amp;nbsp;&amp;nbsp;&amp;nbsp; 在&lt;b&gt;Preprocessor Definitions&lt;/b&gt;中定義巨集(&lt;b&gt;API_BUILD_DLL&lt;/b&gt;),其作用是讓上面的巨集指令知道此&lt;b&gt;DLL&lt;/b&gt;專案要使用&lt;b&gt;__declspec(dllexport) &lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXAb0DRZaoshbs4ZMRflayr7gat9pYEkxn1cb4-WZ2qjxmQfA4e7YRv9T-o47hBVs_TMbggQNZ60f8wDdCYt5p5GbMRpps7mYk3eIH5C9vn-ukuKdjiuzJzDAzeCco6FyKdxULWpXmRsQY/s1600/5.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXAb0DRZaoshbs4ZMRflayr7gat9pYEkxn1cb4-WZ2qjxmQfA4e7YRv9T-o47hBVs_TMbggQNZ60f8wDdCYt5p5GbMRpps7mYk3eIH5C9vn-ukuKdjiuzJzDAzeCco6FyKdxULWpXmRsQY/s1600/5.jpg&quot; /&gt;&amp;nbsp;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;6.&amp;nbsp;&amp;nbsp;&amp;nbsp; 在class的title上加上巨集的定義(&lt;b&gt;C3DMATHS_CLASS&lt;/b&gt;), 表示將此class匯出 &lt;/div&gt;&lt;br /&gt;
&lt;pre class=&quot;c++&quot; name=&quot;code&quot;&gt;class  C3DMATHS_CLASS  C3DVector
{

public:
    C3DVector(void);
    ~C3DVector(void);

    C3DVector(float X, float Y, float Z);
    void Set(float X, float Y, float Z);
    float Length(void);
    void Normalize(void);
}
&lt;/pre&gt;&lt;br /&gt;
7.&amp;nbsp;&amp;nbsp;&amp;nbsp; 按下&lt;b&gt;Rebuild Sloution&lt;/b&gt; 鍵，即可產生&lt;b&gt;C3DMaths.dll&lt;/b&gt;和&lt;b&gt;C3DMaths.lib&lt;/b&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXHmqAwjCmv13GPue-BTmqqM9TmyYIf2CVkbPFGGf-oEE9CR9zFAmEaSHKVRsfamdvQogOj_ompuUWvVyCWyspuvdR4jbY1oPf5oO_NWWitkOSGzwRLynAY8ppZhruEnRZLCjWTatZXggM/s1600/6.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXHmqAwjCmv13GPue-BTmqqM9TmyYIf2CVkbPFGGf-oEE9CR9zFAmEaSHKVRsfamdvQogOj_ompuUWvVyCWyspuvdR4jbY1oPf5oO_NWWitkOSGzwRLynAY8ppZhruEnRZLCjWTatZXggM/s1600/6.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;APP使用DLL的步驟 &lt;/b&gt;&lt;br /&gt;
程式中使用&lt;b&gt;DLL&lt;/b&gt;需要有.h檔, .lib檔和.dl檔, 其中.h檔和.lib檔必須加入到使用&lt;b&gt;DLL&lt;/b&gt;的專案中, 而.dll檔則需要放在應用程式所在的路徑(通常和.exe檔同一路徑), 步驟如下:&lt;br /&gt;
&lt;br /&gt;
1.&amp;nbsp;&amp;nbsp;&amp;nbsp; 建立一隻Console的程式(MainDLLTest.exe)&lt;br /&gt;
2.&amp;nbsp;&amp;nbsp;&amp;nbsp; 將&lt;b&gt;C3DMath&lt;/b&gt;專案所產生的h檔、lib檔，複製到&lt;b&gt;MainDLLTest&lt;/b&gt;的專案底下&lt;br /&gt;
3.&amp;nbsp;&amp;nbsp;&amp;nbsp; 引入標頭檔(C3DMath.h)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;background-color: #cccccc;&quot;&gt; #include &quot;.\C3DMaths\C3DMath.h&quot;&lt;/span&gt;&lt;br /&gt;
4.&amp;nbsp;&amp;nbsp;&amp;nbsp; 連結lib檔&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 點選&lt;b&gt;Property Page&lt;/b&gt;--&amp;gt;&lt;b&gt;Linker&lt;/b&gt;--&amp;gt;&lt;b&gt;Input&lt;/b&gt;--&amp;gt;&lt;b&gt;Additional Dependencies&lt;/b&gt;，然後輸入lib檔的路徑&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil3y6wA3WA3TcxeyB0eF0CsvIjfKoChOXkMiz9ATbwgCUsncYKJZeGBNudzNkpacZQMhZUTY2D_GSrkhC6nMVpfe80z2TaTtiU5Dbvk7wQa45baSComVR8FibtBl_hdl4PrdqJpmxLxqOP/s1600/7.jpg&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil3y6wA3WA3TcxeyB0eF0CsvIjfKoChOXkMiz9ATbwgCUsncYKJZeGBNudzNkpacZQMhZUTY2D_GSrkhC6nMVpfe80z2TaTtiU5Dbvk7wQa45baSComVR8FibtBl_hdl4PrdqJpmxLxqOP/s1600/7.jpg&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil3y6wA3WA3TcxeyB0eF0CsvIjfKoChOXkMiz9ATbwgCUsncYKJZeGBNudzNkpacZQMhZUTY2D_GSrkhC6nMVpfe80z2TaTtiU5Dbvk7wQa45baSComVR8FibtBl_hdl4PrdqJpmxLxqOP/s1600/7.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;br /&gt;
&lt;/a&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil3y6wA3WA3TcxeyB0eF0CsvIjfKoChOXkMiz9ATbwgCUsncYKJZeGBNudzNkpacZQMhZUTY2D_GSrkhC6nMVpfe80z2TaTtiU5Dbvk7wQa45baSComVR8FibtBl_hdl4PrdqJpmxLxqOP/s1600/7.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;br /&gt;
&lt;/a&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil3y6wA3WA3TcxeyB0eF0CsvIjfKoChOXkMiz9ATbwgCUsncYKJZeGBNudzNkpacZQMhZUTY2D_GSrkhC6nMVpfe80z2TaTtiU5Dbvk7wQa45baSComVR8FibtBl_hdl4PrdqJpmxLxqOP/s1600/7.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
5. 複製.dll檔(&lt;b&gt;C3DMaths.dl&lt;/b&gt;l)到應用程式執行路徑下(&lt;b&gt;MainDLLTest.exe&lt;/b&gt;), 即可執行程式來測試&lt;b&gt;DLL&lt;/b&gt;的功能&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjF2yRvtYOB33YCl79dbjhWksxJ32mY2JlILyUwNYD9w69LxK4vPotpTBIe4dCQNwD40EZEEdLdKn7azs8thbpYcpcWLwlUtNcc9fwOD-ZuzDKVnxEcAhtVurAo-uJCMgyNiwo92NZjJ9c/s1600/8.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjF2yRvtYOB33YCl79dbjhWksxJ32mY2JlILyUwNYD9w69LxK4vPotpTBIe4dCQNwD40EZEEdLdKn7azs8thbpYcpcWLwlUtNcc9fwOD-ZuzDKVnxEcAhtVurAo-uJCMgyNiwo92NZjJ9c/s1600/8.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXC4bXi-k5k28bR9r9gZRRfLKcaW3D0x4dO5hkPQjmTNMClDD8X3LMstyDBjlybxpaj4pM9R0K3lNQMG21d5FMXcndiouYSNWJ6dc6g-Ku5KxViwfS2k2sbqzg2iEwD1TnBiFqaPrPGbmw/s1600/10.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXC4bXi-k5k28bR9r9gZRRfLKcaW3D0x4dO5hkPQjmTNMClDD8X3LMstyDBjlybxpaj4pM9R0K3lNQMG21d5FMXcndiouYSNWJ6dc6g-Ku5KxViwfS2k2sbqzg2iEwD1TnBiFqaPrPGbmw/s1600/10.jpg&quot; /&gt;&amp;nbsp;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;編譯環境的設定&lt;/b&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;在&lt;b&gt;VC&lt;/b&gt;中可以利用一些巨集指令來設定你的編譯環境，不但可方便管理專案，也節省很多人工的時間，尤其在開發大型專案時，自動build的流程就變得很重要。下面介紹的方法，可用來自動產生使用&lt;b&gt;DLL&lt;/b&gt;時，所要引用的檔案和資料夾，如此一來可省去人工複製的麻煩和時間。&lt;/div&gt;&lt;br /&gt;
首先看一下&lt;b&gt;VC&lt;/b&gt;項目設置中可以使用的巨集，常用的有：&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXT4zyCfsQPe7hXL3kuEnQIs4Ke931YmxQpTyjiIzfCm5Nc1ayofGNZQlFJ4fjZH9owH5jP1bMT3idLc7jKxJhPIr-NgyiEuTKbvHMfhlyKhmFi3ticXZuxRTgzvyt-J3ApKYtjb2bYFXl/s1600/11.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXT4zyCfsQPe7hXL3kuEnQIs4Ke931YmxQpTyjiIzfCm5Nc1ayofGNZQlFJ4fjZH9owH5jP1bMT3idLc7jKxJhPIr-NgyiEuTKbvHMfhlyKhmFi3ticXZuxRTgzvyt-J3ApKYtjb2bYFXl/s1600/11.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp;1.&amp;nbsp;&amp;nbsp; &amp;nbsp;設定dll檔的輸出路徑&lt;br /&gt;
&lt;b&gt;General &lt;/b&gt;--&amp;gt;&lt;b&gt;Output Directory&lt;/b&gt; --&amp;gt;&amp;nbsp;&lt;b&gt; $(PlatformName)\$(ConfigurationName)&lt;/b&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPplZYapqAzEuChylCGSkD8dgE2mUYumyWpwOvuSZFhwHvegkailrJGKwYCt6tMlRhC9M6VwiahvWpgtVLsstERRR9XRi8NHweyudAI-e0IWFMstrPcbSxQdDlRbw7X7XMm1E7oOInPY8N/s1600/13.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPplZYapqAzEuChylCGSkD8dgE2mUYumyWpwOvuSZFhwHvegkailrJGKwYCt6tMlRhC9M6VwiahvWpgtVLsstERRR9XRi8NHweyudAI-e0IWFMstrPcbSxQdDlRbw7X7XMm1E7oOInPY8N/s1600/13.jpg&quot; /&gt;&amp;nbsp;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;2.&amp;nbsp;&amp;nbsp;&amp;nbsp; 設定lib檔的輸出路徑&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;b&gt;Linker&lt;/b&gt;-&amp;gt;&lt;b&gt;Advance&lt;/b&gt;-&amp;gt;&lt;b&gt;ImportLibrary &lt;/b&gt;--&amp;gt;&lt;b&gt;\$(PlatformName)\$(ConfigurationName)/$(TargetName).lib&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHkDWw1aV9Kglfpb8HJ5QqexdUfZ-GHIgUBqeY1qXPTpCv19BvcALgrckYXfCvwQosnnUtQNEm-ekusRZ3qd9Lp8ykXH5rLxE6PG4i7vdyLUA3xTd13XixX8x92ra8fYa4Nu08WkJaq92H/s1600/14.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHkDWw1aV9Kglfpb8HJ5QqexdUfZ-GHIgUBqeY1qXPTpCv19BvcALgrckYXfCvwQosnnUtQNEm-ekusRZ3qd9Lp8ykXH5rLxE6PG4i7vdyLUA3xTd13XixX8x92ra8fYa4Nu08WkJaq92H/s1600/14.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
3.&amp;nbsp;&amp;nbsp; &amp;nbsp;利用&lt;b&gt;Post Build Event&lt;/b&gt;複製檔案&lt;br /&gt;
這個功能大多是當你在開發 &lt;b&gt;DLL &lt;/b&gt;專案，編譯完成後，直接將編譯結果複製到會使用的專案目錄中。這樣就不用, 每次還要開檔案總管進行複製了。輸入的指令如下所示&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #cccccc;&quot;&gt;產生專案目錄&lt;br /&gt;
mkdir&amp;nbsp; &quot;.\$(ProjectName)&quot;&amp;nbsp; &lt;/div&gt;&lt;div style=&quot;background-color: #cccccc;&quot;&gt;&lt;br /&gt;
產生Debug或Release目錄&lt;br /&gt;
mkdir&amp;nbsp; &quot;.\$(ProjectName)\$(PlatformName)\$(ConfigurationName)&quot; &lt;/div&gt;&lt;div style=&quot;background-color: #cccccc;&quot;&gt;&lt;br /&gt;
複製lib檔&lt;br /&gt;
COPY&quot;.\$(PlatformName)\$(ConfigurationName)\$(TargetName).lib&quot;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;.\$(ProjectName)\$(PlatformName)\$(ConfigurationName)&quot; &lt;br /&gt;
&lt;br /&gt;
複製dll檔&lt;br /&gt;
COPY &quot;$(TargetPath)&quot; &quot;.\$(ProjectName)\$(PlatformName)\$(ConfigurationName)&quot;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #cccccc;&quot;&gt;複製h檔&lt;br /&gt;
COPY &quot;C3DMatrix.h&quot; &quot;.\$(ProjectName)&quot;&amp;nbsp;&lt;/div&gt;&lt;span style=&quot;background-color: #cccccc;&quot;&gt;COPY  &quot;C3DVector.h&quot; &quot;.\$(ProjectName)&quot; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt; &lt;br /&gt;
&lt;span style=&quot;background-color: #cccccc;&quot;&gt;COPY &quot;C3DMathLoader.h&quot; &quot;.\$(ProjectName)&quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxt0x7QumxoDbNWFcbsJvgMyKOMj9WsQsjItC-7jdpB2KZnv22ucRraI-I8I35XoIJbqlgk6nBn3qF_9_hDX2vxZWTbpEb4dkS1k8_IUtloRG4s1eprXJFULW0tAJ-HybVLw5ZM3Gf5bDA/s1600/15.jpg&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxt0x7QumxoDbNWFcbsJvgMyKOMj9WsQsjItC-7jdpB2KZnv22ucRraI-I8I35XoIJbqlgk6nBn3qF_9_hDX2vxZWTbpEb4dkS1k8_IUtloRG4s1eprXJFULW0tAJ-HybVLw5ZM3Gf5bDA/s1600/15.jpg&quot; /&gt;&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/3832217580759991806/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2010/12/dll.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/3832217580759991806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/3832217580759991806'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2010/12/dll.html' title='DLL的製作和使用'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyRtYTLwJYNxHcqGD6647zfGSr4y2KggMSAsg4FjP6iebNuFH_kTkZ-SOz2NNpPCqgB2cykt_9OM1MwkbIJCnlcK3THO14kOoCu0oRIRxgahTcMZnBQmtKZRPFL9vPoozR8jg7uviIIx-7/s72-c/1.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-808450973296536859</id><published>2010-12-01T02:48:00.000-08:00</published><updated>2010-12-01T17:29:34.408-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><title type='text'>在C++ Class中使用callback function</title><content type='html'>&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif; font-size: small;&quot;&gt;在&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: Arial,Helvetica,sans-serif; font-size: small;&quot;&gt;&lt;b&gt;C++&lt;/b&gt; &lt;/span&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif; font-size: small;&quot;&gt;的類別中如何使用&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;API&lt;/span&gt;&lt;/b&gt;的&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: Arial,Helvetica,sans-serif; font-size: small;&quot;&gt;&lt;b&gt;callback function&lt;/b&gt;, &lt;/span&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif; font-size: small;&quot;&gt;相信這是剛學會&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;callback function&lt;/span&gt;&lt;/b&gt;程式員會遇到的問題&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: Arial,Helvetica,sans-serif; font-size: small;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif; font-size: small;&quot;&gt;所以在這整理一下解決的方法&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;background-color: #cfe2f3; font-family: Arial,Helvetica,sans-serif; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;1.&lt;span style=&quot;font-size-adjust: none; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;若&lt;span lang=&quot;EN-US&quot;&gt;callback function&lt;/span&gt;要成為類別的&lt;span lang=&quot;EN-US&quot;&gt;member function&lt;/span&gt;必須宣告成&lt;span lang=&quot;EN-US&quot;&gt;static&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;br /&gt;
&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;解析 - 首先, 我們先來釐清類別中的成員函式, 是如何存取成員變數(注意: 記憶體中只會有一份類別成員函式, 而類別成員變數可能有好幾份).&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;
關鍵就是透過&lt;b&gt;this&lt;/b&gt;指標. 因為, &lt;b&gt;C++&lt;/b&gt;在編譯時, 會隱含&lt;b&gt;this&lt;/b&gt;指標在類別的成員函式中&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;例如有一個類別和其成員函式為:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;pre class=&quot;c++&quot; name=&quot;code&quot;&gt;class CShape
{
...
public:

void SetColor(int color) { m_color = color;};
}
&lt;/pre&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;經過編譯後&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;會變成&lt;/span&gt;&lt;/div&gt;&lt;pre class=&quot;c++&quot; name=&quot;code&quot;&gt;class CShape
{
...
public:
    void SetColor(int color, (CShape*)this) { this-&amp;gt;m_color = color; }
};
&lt;/pre&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;因此&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;透過&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;this&lt;/span&gt;&lt;/b&gt;指標可用來指向呼叫它的物件&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;(&lt;b&gt;instance&lt;/b&gt;), &lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;進而存取各自的成員變數&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;而&lt;b&gt;callback function&lt;/b&gt;通常是由系統呼叫, 也就是系統不需經由任何物件呼叫此函式,&amp;nbsp;  因此member callback function的&lt;b&gt; this&lt;/b&gt; 指標會沒有指向任何實體物件, 這將會造成錯誤.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: left;&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;為了不要讓&lt;b&gt;callback function&lt;/b&gt;自動含有&lt;b&gt;this&lt;/b&gt;指標, 可以將&lt;b&gt;callback function&lt;/b&gt;宣告成&lt;b&gt;static member function.&lt;/b&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;如此一來, &lt;b&gt;callback function&lt;/b&gt;就變成 &lt;b&gt;global function&lt;/b&gt;, 不需透過物件的實體就可呼叫. &lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;font-family: Arial,Helvetica,sans-serif; margin-left: 18pt; text-indent: -18pt;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b style=&quot;background-color: #cfe2f3;&quot;&gt;2.&amp;nbsp;&amp;nbsp; 若要在&lt;span lang=&quot;EN-US&quot;&gt;callback function&lt;/span&gt;中存取類別成員變數或成員函式&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;需要修改&lt;span lang=&quot;EN-US&quot;&gt;callback function prototype, &lt;/span&gt;讓函式的參數列中&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;可傳入&lt;span lang=&quot;EN-US&quot;&gt;this&lt;/span&gt;指標&lt;span lang=&quot;EN-US&quot;&gt;.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: small;&quot;&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;解析 - 由於&lt;/span&gt;&lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;static member function&lt;/b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;是屬於類別而不是物件, 所以呼叫&lt;b&gt;s&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;tatic member function&lt;/b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;時, 不會傳入物件的位址, 所以&lt;b&gt;s&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;tatic member function&lt;/b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;中不會有&lt;/span&gt;&lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;this&lt;/b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;指標, 因此,&lt;/span&gt;&lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt; static member function&lt;/b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;中不允許使用&lt;b&gt;non-static&lt;/b&gt;成員.&lt;/span&gt;&lt;br style=&quot;font-family: Arial,Helvetica,sans-serif;&quot; /&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: small;&quot;&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;所以, 如果要在&lt;/span&gt;&lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;static callback function&lt;/b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;中存取&lt;b&gt;non-static&lt;/b&gt;成員, 需要在&lt;b&gt;c&lt;/b&gt;&lt;/span&gt;&lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;allback functuon&lt;/b&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;的參數列表中傳入物件的&lt;/span&gt;&lt;b style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;this&lt;/b&gt;&lt;span style=&quot;font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;&quot;&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;指標&lt;/span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: small;&quot;&gt;&lt;span style=&quot;font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;&quot;&gt;&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;例如&lt;b&gt;API&lt;/b&gt;中有一個&lt;b&gt;callback function&lt;/b&gt;宣告如下:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: small;&quot;&gt;&lt;span style=&quot;font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style=&quot;background-color: yellow; font-family: Arial,Helvetica,sans-serif;&quot;&gt;void (*TouchCallback)(TouchPoint p);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: small;&quot;&gt;&lt;span style=&quot;font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;&quot;&gt;若要成為類別的成員函式, 可改為:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: small;&quot;&gt;&lt;span style=&quot;font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;span style=&quot;font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;&quot;&gt;&lt;span style=&quot;background-color: yellow; font-family: Arial,Helvetica,sans-serif;&quot;&gt;void (*TouchCallback)(TouchPoint p, void* pInstance);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;span style=&quot;font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: small;&quot;&gt;&lt;span style=&quot;font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;下面為範例:&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;有一個&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;&lt;b&gt;Touch API&lt;/b&gt;, &lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;它利用&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;callback&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;的方法來取得觸控點資料&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;其介面如下:&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;pre class=&quot;c++&quot; name=&quot;code&quot;&gt;#ifdef  TOUCHAPI_EXPORTS
  #define TOUCH_API __declspec(dllexport)
#else
  #define TOUCH_API __declspec(dllimport)
#endif

// 定義觸控點的相關資訊
struct TouchPoint
{
 int X; 

 int Y; 
};

// 定義可傳入this指標的callback function prototype
typedef void (_stdcall *CB_TOUCH_CLASS_FUNC) (TouchPoint, void* pObject);

// 定義了一個RegisterCBTouchMemberFunc的函式,
// 可傳入一個具有CB_TOUCH_FUNC型別的callback function
TOUCH_API void RegisterCBTouchMemberFunc(CB_TOUCH_CLASS_FUNC callback,void* pObject);
&lt;/pre&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;定義&lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;一個&lt;/span&gt;&lt;b&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;CTouchClass&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-size: small;&quot;&gt;的類別&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;必且利用&lt;/span&gt;&lt;b&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;Touch API&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-size: small;&quot;&gt;的&lt;/span&gt;&lt;b&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;callback function &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-size: small;&quot;&gt;作為&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: small;&quot;&gt;&lt;b&gt;member function&lt;/b&gt;, &lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;程式碼如下:&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;TouchClass.h&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;pre class=&quot;c++&quot; name=&quot;code&quot;&gt;#include &quot;TouchAPI.h&quot;
class CTouchClass
{
private:
 int m_x;
 int m_y;

public:
 CTouchClass(void);
 ~CTouchClass(void);

public:
 static void _stdcall TouchCallback(TouchPoint point, void* pObject);

public: 
 int GetTouchX();
 int GetTouchY();

};
&lt;/pre&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;TouchClass.cpp&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;pre class=&quot;c++&quot; name=&quot;code&quot;&gt;#include &quot;StdAfx.h&quot;
#include &quot;TouchClass.h&quot;

CTouchClass::CTouchClass(void)
{
    this-&amp;gt;m_x = 0;
    this-&amp;gt;m_y = 0;
}

CTouchClass::~CTouchClass(void)
{
   this-&amp;gt;m_x = 0;
   this-&amp;gt;m_y = 0;
}

// 利用this指標存取member function
void CTouchClass::TouchCallback(TouchPoint point, void* pObject)
{
   CTouchClass* pClass =  (CTouchClass*)pObject;
   pClass-&amp;gt;m_x = point.X;
   pClass-&amp;gt;m_y = point.Y;
}
 
int CTouchClass::GetTouchX()
{
   return m_x;
}
    
int CTouchClass::GetTouchY()
{
   return m_y;
}
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/808450973296536859/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2010/12/c-classcallback-function.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/808450973296536859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/808450973296536859'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2010/12/c-classcallback-function.html' title='在C++ Class中使用callback function'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-7111810873847307428</id><published>2010-11-24T19:16:00.000-08:00</published><updated>2010-11-26T00:44:27.976-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><title type='text'>如何在C#中使用C++ Class DLL</title><content type='html'>&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;在&lt;a href=&quot;http://johnniebooks.blogspot.com/2009/08/cunmanaged-dll.html&quot;&gt;如何在C#中使用Unmanaged dll&lt;/a&gt; 文章中曾介紹&lt;b&gt;C#&lt;/b&gt;中使用&lt;b&gt;C++ &lt;/b&gt;函式庫(&lt;b&gt;DLL&lt;/b&gt;)的方法, 不過此方法僅適用於&lt;b&gt;C-Style export&lt;/b&gt; 出來的函式, 不行用在類別(&lt;b&gt;Class&lt;/b&gt;)中的成員函式.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: small;&quot;&gt;但其實很多&lt;b&gt;API&lt;/b&gt;都是設計成&lt;b&gt;C++&lt;/b&gt;的類別, 因此本文將介紹如何在&lt;b&gt;C# &lt;/b&gt;使用&lt;b&gt;C++ Class&lt;/b&gt;的函式.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;其步驟如下:&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;ul style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;li style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;設計一個C-Style function 介面, 透過指標存取物件的實體&lt;/b&gt; – 由於&lt;b&gt;C#&lt;/b&gt;中並沒有提供包裝&lt;b&gt;C++ Class&lt;/b&gt;的方法, 所以我們必須將類別中&lt;b&gt;public function&lt;/b&gt;重新包裝成&lt;b&gt;C-Style function&lt;/b&gt;, 而一個物件的實體, 其實可以透過指標(*)作存取, &lt;b&gt;C#&lt;/b&gt;中指標的使用也可透過&lt;/span&gt;&lt;span style=&quot;color: #073763; font-size: small;&quot;&gt;IntPtr&lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;. &lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;利用C# PInvoke機制呼叫C-Style function&lt;/b&gt;– 作法可參考&lt;a href=&quot;http://johnniebooks.blogspot.com/2009/08/cunmanaged-dll.html&quot;&gt;如何在C#中使用Unmanaged dll&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;釋放unmanaged object記憶體&lt;/b&gt; –由於&lt;b&gt;C#&lt;/b&gt;的回收機制,不會自動回收unmanaged object記憶體, 所以我們必須透過&lt;b&gt;Dispose/Finalize&lt;/b&gt;手動回收, 其作法可參考&lt;a href=&quot;http://johnniebooks.blogspot.com/2010/05/c.html&quot;&gt;C#記憶體管理&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;範例如下&lt;span lang=&quot;EN-US&quot;&gt;:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;原始C++類別程式碼 &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;#ifdef CSHAPEAPI_EXPORTS
 #define  CSHAPE_API  __declspec(dllexport)
#else
 #define  CSHAPE_API  __declspec(dllimport)
#endif


class CSHAPE_API CShape
{

public:
 CShape(){};
 virtual ~CShape(){};

public:
 float GetRectangleArea(float w ,float h) { return w*h; };  
 float GetTriangleArea(float b ,float h) { return 0.5*b*h;};
};
&lt;/pre&gt;&lt;div style=&quot;font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;另外設計一個C-Style function 介面, 包裝要使用的C++ 類別&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;CShapeBridge.h&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre class=&quot;c++&quot; name=&quot;code&quot;&gt;#include &quot;CShapeAPI.h&quot;
#ifdef __cplusplus
extern &quot;C&quot; {
#endif

extern CSHAPE_API CShape* CreateInstance();
extern CSHAPE_API void DisposeInstance(CShape* pShapeInstance);

extern CSHAPE_API float GetRectangleArea(CShape* pShapeInstance,
                                        float w ,float h);  
extern CSHAPE_API float GetTriangleArea(CShape* pShapeInstance,
                                        float b ,float h);


#ifdef __cplusplus
}
#endif
&lt;/pre&gt;&lt;div style=&quot;font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;CShapeBridge.cpp&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;pre class=&quot;c++&quot; name=&quot;code&quot;&gt;#include &quot;stdafx.h&quot;
#include &quot;CShapeBridge.h&quot;

extern &quot;C&quot;  CSHAPE_API CShape* CreateInstance()
{
 return new CShape();
}

extern &quot;C&quot;  CSHAPE_API void DisposeInstance(CShape* pShapeInstance)
{
 if(pShapeInstance != NULL)
 {
  delete pShapeInstance;
  pShapeInstance = NULL;
 }
}

extern &quot;C&quot;  CSHAPE_API float GetRectangleArea(CShape* pShapeInstance, 
                                              float w ,float h)
{

 return pShapeInstance-&amp;gt;GetRectangleArea(w, h);
}

extern &quot;C&quot;  CSHAPE_API float GetTriangleArea(CShape* pShapeInstance, 
                                             float b ,float h)
{
 return pShapeInstance-&amp;gt;GetTriangleArea(b, h);
}
&lt;/pre&gt;&lt;div style=&quot;font-family: Times,&amp;quot;Times New Roman&amp;quot;,serif;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;b&gt;利用PInvoke機制呼叫C-Style function , 並釋放unmanaged object記憶體&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;
&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;ShapeWrapper.cs
using System;
using System.Runtime.InteropServices;

namespace ShapeTest
{
    public class ShapeWrapper : IDisposable
    {
        #region PInvokes
        [DllImport(&quot;CShapeAPI.dll&quot;)]
        private static extern IntPtr CreateInstance();

        [DllImport(&quot;CShapeAPI.dll&quot;)]
        private static extern void DisposeInstance(IntPtr pShapeInstance);

        [DllImport(&quot;CShapeAPI.dll&quot;)]
        private static extern float GetRectangleArea(IntPtr pShapeInstance,
                                                     float w, float h);  
       
        [DllImport(&quot;CShapeAPI.dll&quot;)]
        private static extern float GetTriangleArea(IntPtr pShapeInstance, 
                                                    float b, float h);
        #endregion

        #region Members
        // Variable to hold the C++ class&#39;s this pointer
        private IntPtr m_pNativeObject;  
        #endregion Members


        public ShapeWrapper()
        {
            // We have to Create an instance of 
            // this class through an exported function
            this.m_pNativeObject = CreateInstance();
        }

        public void Dispose()
        {
            Dispose(true);
        }

        protected virtual void Dispose(bool bDisposing)
        {
            if (this.m_pNativeObject != IntPtr.Zero)
            {
                // Call the DLL Export to dispose this class
                DisposeInstance(this.m_pNativeObject);
                this.m_pNativeObject = IntPtr.Zero;
            }

            if (bDisposing)
            {
                // No need to call the finalizer since we&#39;ve now cleaned
                // up the unmanaged memory
                GC.SuppressFinalize(this);
            }
        }

        // This finalizer is called when Garbage collection occurs, but only if
        // the IDisposable.Dispose method wasn&#39;t already called.
        ~ShapeWrapper()
        {
            Dispose(false);
        }


        #region Wrapper methods
        public float GetRectangleArea(float w, float h)
        {

            return GetRectangleArea(m_pNativeObject, w, h);
        }

        public float GetTriangleArea(float b, float h)
        {
            return GetTriangleArea(m_pNativeObject, b, h);
        }
        #endregion
    }
}

&lt;/pre&gt;&lt;br /&gt;
&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;b&gt;測試C#程式使用C++ Class DLL&lt;/b&gt;&lt;/div&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;using System;
namespace ShapeTest
{
    class Program
    {
        static void Main(string[] args)
        {
            ShapeWrapper shape = new ShapeWrapper();

            float w= 25.0f;
            float h= 10.0f;
            Console.WriteLine(&quot;Rectangle area = &quot;+shape.GetRectangleArea(w, h));


            float b = 30.0f;
            float h1 = 20.0f;
            Console.WriteLine(&quot;Triangle area = &quot;+ shape.GetTriangleArea(b, h1));

        }
    }
}&amp;nbsp;
&lt;/pre&gt;&lt;br /&gt;
&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;b&gt;測試結果:&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;Rectangle area = 250&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;Triangle area = 300 &lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;另外, &lt;b&gt;MSDN&lt;/b&gt;也有提供使用&lt;b&gt;CLR&lt;/b&gt;的方法, 請參考&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/ms235281.aspx&quot;&gt;包裝原生類別以便讓 C# 使用&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;b&gt;參考文章&lt;/b&gt;:&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;a href=&quot;http://www.codeproject.com/KB/cs/marshalCPPclass.aspx&quot;&gt;How to Marshal a C++ Class&lt;/a&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/7111810873847307428/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2010/11/cc-class-dll.html#comment-form' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/7111810873847307428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/7111810873847307428'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2010/11/cc-class-dll.html' title='如何在C#中使用C++ Class DLL'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-8614497650984560611</id><published>2010-11-11T03:04:00.000-08:00</published><updated>2010-11-11T06:12:30.151-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><title type='text'>Background Process in WPF</title><content type='html'>&lt;div style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;在程式執行中&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;有時後需要處理一些比較耗時的程序&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;例如讀取或計算大量的資料&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;因為這些動作會花比較多的時間&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;而且會讓畫面停留不動&lt;span lang=&quot;EN-US&quot;&gt;. &lt;/span&gt;所以&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;通常需要一個&lt;span lang=&quot;EN-US&quot;&gt;Loading/Processing&lt;/span&gt;的畫面來提醒使用者&lt;span lang=&quot;EN-US&quot;&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: Arial, Helvetica, sans-serif; text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: Arial, Helvetica, sans-serif; text-align: justify;&quot;&gt;在&lt;span lang=&quot;EN-US&quot;&gt;Loading&lt;/span&gt;過程中&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;如果要更新&lt;span lang=&quot;EN-US&quot;&gt;UI&lt;/span&gt;內容的話&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;需要在背景工作&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;否則會等&lt;span lang=&quot;EN-US&quot;&gt;Loading&lt;/span&gt;處理完畢後&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;才會更新&lt;span lang=&quot;EN-US&quot;&gt;UI.&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: Arial, Helvetica, sans-serif; text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: Arial, Helvetica, sans-serif; text-align: justify;&quot;&gt;下面的範例中&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;程式會顯示&lt;span lang=&quot;EN-US&quot;&gt;Loading&lt;/span&gt;過程中的次數和完成的百分比.&lt;/div&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;private void UpdateProcess()
 {
     for (int i = 1; i &amp;lt;= _numberOfTasks; i++)
     {
         labelNumber.Content = i +&quot;/&quot; + _numberOfTasks;
         float percentageDone = (i / (float)_numberOfTasks) * 100f;
         labelPercent.Content = (int)percentageDone+&quot;%&quot;;
         Thread.Sleep(1);
     }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;div style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;從執行結果可看出&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;因為不是在背景中&lt;span lang=&quot;EN-US&quot;&gt;(background)&lt;/span&gt;更新&lt;span lang=&quot;EN-US&quot;&gt;UI&lt;/span&gt;內容&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;所以畫面會停住不動&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;等&lt;span lang=&quot;EN-US&quot;&gt;Loading&lt;/span&gt;完才會更新&lt;span lang=&quot;EN-US&quot;&gt;UI&lt;/span&gt;內容&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: center;&quot;&gt;&lt;iframe allowfullscreen=&#39;allowfullscreen&#39; webkitallowfullscreen=&#39;webkitallowfullscreen&#39; mozallowfullscreen=&#39;mozallowfullscreen&#39; width=&#39;320&#39; height=&#39;266&#39; src=&#39;https://www.blogger.com/video.g?token=AD6v5dwIZZB1ekER-h8EOgk4KexLDFQcuVfMsz6j1Z0qG8dNTWHkOkhvfVQi7uDTrdPPOXPyvTuaO3R2LGpwh5Axmg&#39; class=&#39;b-hbp-video b-uploaded&#39; frameborder=&#39;0&#39;&gt;&lt;/iframe&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;[影片1] 不在背景工作中更新UI&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;在&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;WPF&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;中提供多個背景工作的方法&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;下面逐一介紹&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;strong&gt;1. 使用&lt;/strong&gt;&lt;/span&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.threading.dispatcher%28VS.95%29.aspx&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;strong&gt;Dispatcher&lt;/strong&gt;&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt; &lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: Arial, Helvetica, sans-serif; text-align: left;&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;此方法最為簡單, 我們可將&lt;/span&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.threading.dispatcherpriority.aspx&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Dispatcher Priority&lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt; 設成 &lt;b&gt;DispatcherPriority.Background&lt;/b&gt;,即可在背景執行,而&lt;b&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.threading.dispatcher%28VS.95%29.aspx&quot;&gt;Dispatcher&lt;/a&gt;&lt;/b&gt;的相關用法可參考這篇文章&lt;/span&gt;&lt;a href=&quot;http://johnniebooks.blogspot.com/2010/11/wpf-thread-and-dispatcher.html&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;WPF - Thread and Dispatcher&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;因此我們可將上面的程式碼, 改成為下面的程式:&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;private delegate void UpdateProcessDelegate(int index, int percent);
private void UpdateProcessAction(int index, int percent)
{
    labelNumber.Content = index + &quot;/&quot; + _numberOfTasks;
    labelPercent.Content = percent + &quot;%&quot;;
 }

 private void UpdateProcess()
 {
     for (int i = 1; i &amp;lt;= _numberOfTasks; i++)
     {
         //labelNumber.Content = i +&quot;/&quot; + _numberOfTasks;
         float percentageDone = (i / (float)_numberOfTasks) * 100f;
         //labelPercent.Content = (int)percentageDone+&quot;%&quot;;

         Dispatcher.Invoke(DispatcherPriority.Background,
                           new UpdateProcessDelegate(UpdateProcessAction),
                           i, 
                           (int)percentageDone);
         
         Thread.Sleep(1);
      }
 }
&lt;/pre&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: center;&quot;&gt;&lt;iframe allowfullscreen=&#39;allowfullscreen&#39; webkitallowfullscreen=&#39;webkitallowfullscreen&#39; mozallowfullscreen=&#39;mozallowfullscreen&#39; width=&#39;320&#39; height=&#39;266&#39; src=&#39;https://www.blogger.com/video.g?token=AD6v5dzx7OApcPfEJ4ZqRk7EOrmm8wl4iLdwrVU6nBN6DN-L9OzHn1w5U_a0dpQ13vwzKTi3lOytCEYNCu3liVTF6g&#39; class=&#39;b-hbp-video b-uploaded&#39; frameborder=&#39;0&#39;&gt;&lt;/iframe&gt; &lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;[影片2] 使用Dispatcher更新UI內容&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&amp;nbsp;&lt;/span&gt; &lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;strong&gt;2. 使用&lt;/strong&gt;&lt;/span&gt;&lt;span class=&quot;sentence&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.threading.dispatcherframe.aspx&quot;&gt;&lt;strong&gt;DispatcherFrame&lt;/strong&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: Arial, Helvetica, sans-serif; text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;此作法類似Windows Form的&lt;b&gt;DoEvents&lt;/b&gt;. &lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.threading.dispatcher.pushframe.aspx&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;DispatcherFrame&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt; &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;表示處理暫停之工作項目的迴圈.發送器會處理迴圈中的工作項目佇列. 此迴圈即稱為框架。通常是由應用程式以呼叫 Run 的方式來初始化初始迴圈. &lt;b&gt;PushFrame &lt;/b&gt;進入以 frame 參數表示的迴圈。對該迴圈的每次查看, &lt;b&gt;Dispatcher &lt;/b&gt;都會檢查 &lt;/span&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.threading.dispatcher.pushframe.aspx&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;DispatcherFrame &lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;類別上的 &lt;b&gt;Continue &lt;/b&gt;屬性，以判斷迴圈是否應繼續或停止.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
程式碼如下:&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;public void DoEvents()
{
   DispatcherFrame frame = new DispatcherFrame();
   Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
                                            new DispatcherOperationCallback(ExitFrame),
                                           &amp;nbsp;frame);
   Dispatcher.PushFrame(frame);
}

private object ExitFrame(object f)
{
   ((DispatcherFrame)f).Continue = false;
   return null;
}

private void UpdateProcess()
{
   for (int i = 1; i &amp;lt;= _numberOfTasks; i++)
   {
       labelNumber.Content = i +&quot;/&quot; + _numberOfTasks;
       float percentageDone = (i / (float)_numberOfTasks) * 100f;
       labelPercent.Content = (int)percentageDone+&quot;%&quot;;
       DoEvents();
       Thread.Sleep(1);
    }  
 }
&lt;/pre&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;strong&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;3. 使用&lt;/span&gt;&lt;/strong&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.componentmodel.backgroundworker%28VS.95%29.aspx&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;strong&gt;BackgroundWorker&lt;/strong&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.componentmodel.backgroundworker(VS.95).aspx&quot;&gt;BackgroundWorker&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;可以在個別的執行緒上執行. &lt;b&gt;BackgroundWoker&lt;/b&gt;常用的function如下:&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: left;&quot;&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.componentmodel.backgroundworker.dowork%28VS.95%29.aspx&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;DoWork &lt;/span&gt;&lt;/b&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;-設定背景工作的地方, 會將需要耗時的作業放在此事件處理函式&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.componentmodel.backgroundworker.progresschanged%28VS.95%29.aspx&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;ProgressChanged&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt; &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;- 收進度更新的狀態, UI可在此事件處理函式中作更新&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.componentmodel.backgroundworker.runworkerasync%28VS.95%29.aspx&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;RunWorkerAsync&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt; &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;- 啟動執行緒&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.componentmodel.backgroundworker.runworkercompleted%28VS.95%29.aspx&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;RunWorkerCompleted&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt; &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;- 作業完成時會觸發此事件&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;程式碼如下:&lt;br /&gt;
&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;private void btnShowText_Click(object sender, RoutedEventArgs e)
{
    BackgroundWorker worker = new BackgroundWorker();
    worker.WorkerReportsProgress = true;
    worker.DoWork += new DoWorkEventHandler(DoWork);
    worker.ProgressChanged += new ProgressChangedEventHandler(DuringWork);
    
    // start the background work
    worker.RunWorkerAsync();
 }

 void DoWork(object sender, DoWorkEventArgs e)
 {
     BackgroundWorker worker = sender as BackgroundWorker;
     for (int i = 1; i &amp;lt;= _numberOfTasks; i++)
     {
         if (worker.CancellationPending)
         {
            e.Cancel = true;
            return;
          }
          Thread.Sleep(1);
          float percentageDone = (i / (float)_numberOfTasks) * 100f;
          worker.ReportProgress((int)percentageDone, i);
      }
  }
       
 void DuringWork(object sender, ProgressChangedEventArgs e)
 {
    labelNumber.Content = e.UserState + &quot;/&quot; + _numberOfTasks;
    labelPercent.Content = e.ProgressPercentage.ToString() + &quot;%&quot;;
 }
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;參考文章:&lt;/div&gt;&lt;div style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;a href=&quot;http://www.codeproject.com/Articles/58836/Using-Background-Process-in-WPF.aspx&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp;Using Background Process in WPF&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;a href=&quot;http://codingjames.blogspot.com/2009/10/wpf.html&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;在WPF中使用背景工作(BackgroundWorker) &lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;a href=&quot;http://www.tanguay.info/web/index.php?pg=codeExamples&amp;amp;id=232&quot;&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;How to use BackgroundWorker to run two threads in background which change UI&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;, &amp;quot;serif&amp;quot;;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/8614497650984560611/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2010/11/background-process-in-wpf.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/8614497650984560611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/8614497650984560611'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2010/11/background-process-in-wpf.html' title='Background Process in WPF'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-677146614149355603</id><published>2010-11-10T23:03:00.000-08:00</published><updated>2010-11-10T23:06:56.915-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><title type='text'>WPF - Thread and Dispatcher</title><content type='html'>&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;WPF 執行緒:&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;在&lt;b&gt;WPF&lt;/b&gt;應用程式中主要有兩個執行緒(Thread)：&lt;b&gt;Rendering Thread&lt;/b&gt;和&lt;b&gt;UI Thread &lt;/b&gt;&lt;/div&gt;&lt;ul style=&quot;text-align: justify;&quot;&gt;&lt;li&gt;&lt;b&gt;Rendering Thread&lt;/b&gt;: 在背景中執行並協助UI Thread完成工作&lt;/li&gt;
&lt;li&gt;&lt;b&gt;UI Thread:&lt;/b&gt; 主要負責處理&lt;b&gt;Input&lt;/b&gt;、&lt;b&gt;Event&lt;/b&gt;與程式碼的部分&lt;/li&gt;
&lt;/ul&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;在&lt;b&gt;WPF&lt;/b&gt;中, 所有UI工作和事件都是在&lt;b&gt;UI Thread&lt;/b&gt;上完成. 每個&lt;b&gt;WPF&lt;/b&gt;程式至少有一個&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.aspx&quot;&gt;&lt;b&gt;Dispatcher&lt;/b&gt;&lt;/a&gt;物件和一個&lt;b&gt;UI Thread&lt;/b&gt;. 而大部分&lt;b&gt;WPF&lt;/b&gt;物件的操作都是binding在&lt;b&gt;UI Thread&lt;/b&gt;上，其他的Thread如果想要直接操作這些UI物件, 是不被允許的, 因為只有建立 &lt;b&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcherobject.aspx&quot;&gt;DispatcherObject &lt;/a&gt;&lt;/b&gt;的Thread才可以存取UI物件。例如, 要讓其他的Thread存取 &lt;b&gt;Label&lt;/b&gt; 的 &lt;b&gt;Content &lt;/b&gt;屬性, 將會發生錯誤, 此範例如下所示:&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;設計一個&lt;b&gt;WPF&lt;/b&gt;視窗, 當按下&lt;b&gt;Button&lt;/b&gt;後, 讓&lt;b&gt;Label&lt;/b&gt;顯示按&lt;b&gt;Button&lt;/b&gt;的次數.&lt;br /&gt;
&lt;br /&gt;
C#程式碼如下所示:&lt;br /&gt;
&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;private static int _clickCount = 0;
private void btnShowText_Click(object sender, RoutedEventArgs e)
{
      _clickCount++;
       // Update Label Conten in another thread
       Thread updateThread = new Thread(UpdateText);
       updateThread.Start();
 }
 private void UpdateText()
 {
      labelClickCount.Content = &quot;Click Count= &quot; + _clickCount.ToString();
 }
&lt;/pre&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEKiznqnVH3-7AK2FfMvf4VSmdBp6IpBpI9Ui42daVLfndiDB9zb7R7kuMhHW2NxeYbjCbL46NC9bC2QHD6a5XdOlEfT3AEY2h_bkXkTZKNmVV3fM_HN_zwyvRAZ3_B_ihdXeDjaDXZv4i/s1600/dispatcher+error.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;171&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEKiznqnVH3-7AK2FfMvf4VSmdBp6IpBpI9Ui42daVLfndiDB9zb7R7kuMhHW2NxeYbjCbL46NC9bC2QHD6a5XdOlEfT3AEY2h_bkXkTZKNmVV3fM_HN_zwyvRAZ3_B_ihdXeDjaDXZv4i/s400/dispatcher+error.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;[圖1]無法再另一個Thread中更新UI&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;/div&gt;&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;Dispatcher&lt;/span&gt;用法: &lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;span class=&quot;selflink&quot;&gt;&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;Dispatcher&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;可讓其他的&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;Thread&lt;/span&gt;&lt;/b&gt;在&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;WPF&lt;/span&gt;&lt;/b&gt;中的&lt;b&gt; &lt;span lang=&quot;EN-US&quot;&gt;UI Thread&lt;/span&gt;&lt;/b&gt;上執行程式碼&lt;span lang=&quot;EN-US&quot;&gt;. &lt;b&gt;Dispatcher&lt;/b&gt;&lt;/span&gt;又被稱為&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;WPF&lt;/span&gt;&lt;/b&gt;中的&lt;span lang=&quot;EN-US&quot;&gt;Message Pump&lt;/span&gt;，提供一個機制去發送工作項目給&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;UI Thread&lt;/span&gt;&lt;/b&gt;進行處理&lt;span lang=&quot;EN-US&quot;&gt;. &lt;/span&gt;&amp;nbsp;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;當&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;Dispatcher&lt;/span&gt;&lt;/b&gt;將工作項目轉給&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;UI Thread&lt;/span&gt;&lt;/b&gt;時, 會讓&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;UI Thread&lt;/span&gt;&lt;/b&gt;進入封鎖狀態&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;畫面鎖定, 因為要處理工作項目&lt;span lang=&quot;EN-US&quot;&gt;). &lt;/span&gt;其他的&lt;span lang=&quot;EN-US&quot;&gt;Thread&lt;/span&gt;必須將工作委派給與 &lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;UI Thread&lt;/span&gt;&lt;/b&gt;相關聯的 &lt;span lang=&quot;EN-US&quot;&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.threading.dispatcher%28VS.90%29.aspx&quot;&gt;Dispatcher&lt;/a&gt;. &lt;/span&gt;這可以使用 &lt;span lang=&quot;EN-US&quot;&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.threading.dispatcher.invoke%28VS.90%29.aspx&quot;&gt;Invoke&lt;/a&gt; &lt;/span&gt;或 &lt;span lang=&quot;EN-US&quot;&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.threading.dispatcher.begininvoke%28VS.90%29.aspx&quot;&gt;BeginInvoke&lt;/a&gt; &lt;/span&gt;完成&lt;span lang=&quot;EN-US&quot;&gt;. &lt;/span&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;span class=&quot;sentence&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: Wingdings;&quot;&gt;&lt;span style=&quot;font: 7pt &amp;quot;Times New Roman&amp;quot;;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;sentence&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.threading.dispatcher.invoke.aspx&quot;&gt;Invoke&lt;/a&gt; &lt;/span&gt;是同步呼叫,也就是說,除非&lt;span lang=&quot;EN-US&quot;&gt; UI &lt;/span&gt;執行緒實際完成委派的執行，否則不會返回&lt;span lang=&quot;EN-US&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: Wingdings;&quot;&gt;&lt;span style=&quot;font: 7pt &amp;quot;Times New Roman&amp;quot;;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: Wingdings;&quot;&gt;&lt;span style=&quot;font: 7pt &amp;quot;Times New Roman&amp;quot;;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;sentence&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.threading.dispatcher.begininvoke.aspx&quot;&gt;BeginInvoke&lt;/a&gt; &lt;/span&gt;是非同步的,會立即返回&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;span class=&quot;sentence&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.threading.dispatcher.aspx&quot;&gt;Dispatcher&lt;/a&gt; &lt;/span&gt;會依優先權排列其佇列中項目的順序&lt;span lang=&quot;EN-US&quot;&gt;. &lt;/span&gt;在將項目加入至 &lt;span lang=&quot;EN-US&quot;&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.threading.dispatcher.aspx&quot; id=&quot;ctl00_MTCS_MtViewContentPlaceholder_ctl116_ctl00_ctl26&quot;&gt;Dispatcher&lt;/a&gt; &lt;/span&gt;佇列.&lt;span lang=&quot;EN-US&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;下面的程式碼&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;將說明其解決方法&lt;span lang=&quot;EN-US&quot;&gt;:&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;C#程式碼如下所示:&lt;/div&gt;&lt;br /&gt;
&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;private static int _clickCount = 0;

 // Declare a delegate type for updating UI
 private delegate void UpdateDelegate(int number, string str);
 private void btnShowText_Click(object sender, RoutedEventArgs e)
 {
     _clickCount++;
     Thread updateThread = new Thread(UpdateText);
      updateThread.Start();
 }

 private void UpdateText()
 {
      //labelClickCount.Content = &quot;Click Count= &quot; + _clickCount.ToString();
      // Places the delegate onto the UI Thread&#39;s Dispatcher
      Dispatcher.Invoke(new UpdateDelegate(UpdateClickCountAction),
                                          _clickCount, 
                                          &quot;Click Count = &quot;);
 }

  private void UpdateClickCountAction(int number, string str)
  {
       labelClickCount.Content = str + number.ToString();
  }
&lt;/pre&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGUxbAdH7no2HXh3Rmb9VngnMN8trgyiNmbcEctcXzNIpQ3amQgCQ3U_vZMJbbgMQwg_w58LD7-v7EiyNotFrsfieaWD2mTdIpO1qvjk6oGuhfuROGZUF18bamumjE8YZggb_fYLy39HQM/s1600/DispatcherOK.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;314&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGUxbAdH7no2HXh3Rmb9VngnMN8trgyiNmbcEctcXzNIpQ3amQgCQ3U_vZMJbbgMQwg_w58LD7-v7EiyNotFrsfieaWD2mTdIpO1qvjk6oGuhfuROGZUF18bamumjE8YZggb_fYLy39HQM/s320/DispatcherOK.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;[圖2] 利用Dispatcher執行另一個Thread的function&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;參考文章:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/ms741870.aspx#MtViewDropDownText&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;,&amp;quot;serif&amp;quot;; font-size: 12pt;&quot;&gt;執行緒模型&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/magazine/cc163328.aspx&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;,&amp;quot;serif&amp;quot;; font-size: 12pt;&quot;&gt;使用&lt;span lang=&quot;EN-US&quot;&gt; Dispatcher &lt;/span&gt;建置回應性更佳的應用程式&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: &amp;quot;新細明體&amp;quot;,&amp;quot;serif&amp;quot;; font-size: 12pt;&quot;&gt; &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/677146614149355603/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2010/11/wpf-thread-and-dispatcher.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/677146614149355603'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/677146614149355603'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2010/11/wpf-thread-and-dispatcher.html' title='WPF - Thread and Dispatcher'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEKiznqnVH3-7AK2FfMvf4VSmdBp6IpBpI9Ui42daVLfndiDB9zb7R7kuMhHW2NxeYbjCbL46NC9bC2QHD6a5XdOlEfT3AEY2h_bkXkTZKNmVV3fM_HN_zwyvRAZ3_B_ihdXeDjaDXZv4i/s72-c/dispatcher+error.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-7031865648027614102</id><published>2010-09-08T23:34:00.000-07:00</published><updated>2010-09-08T23:36:29.869-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="3D"/><category scheme="http://www.blogger.com/atom/ns#" term="Multi-touch"/><category scheme="http://www.blogger.com/atom/ns#" term="My Project"/><title type='text'>Touch Game - Rubik&#39;s Cube</title><content type='html'>&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;之前開發過不少touch相關的應用程式, 其中一個就是&lt;b&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;Rubik&#39;s Cube&lt;/span&gt;&lt;/b&gt;(中文叫魔術方塊), 關於它的介紹和玩法, 可參考: &lt;a href=&quot;http://zh.wikipedia.org/zh-tw/%E9%AD%94%E6%96%B9&quot;&gt;維基百科-魔術方塊&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;b&gt;Rubik&#39;s cube&lt;/b&gt;繪圖的部分是透過&lt;b&gt;OpenGL API&lt;/b&gt;, 而觸控和手勢則取得透過&lt;span style=&quot;font-weight: bold;&quot;&gt;Win7 Touch SDK.&lt;/span&gt;&lt;/div&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;此遊戲可以利用 &quot;觸控+手勢&quot; 來作操作, 方法如下所示:&lt;/span&gt;&lt;br /&gt;
&lt;style&gt;
 &lt;!--  /* Font Definitions */  @font-face 	{font-family:新細明體; 	panose-1:2 2 3 0 0 0 0 0 0 0; 	mso-font-alt:PMingLiU; 	mso-font-charset:136; 	mso-generic-font-family:roman; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 22 0 1048577 0;} @font-face 	{font-family:&quot;Cambria Math&quot;; 	panose-1:2 4 5 3 5 4 6 3 2 4; 	mso-font-charset:1; 	mso-generic-font-family:roman; 	mso-font-format:other; 	mso-font-pitch:variable; 	mso-font-signature:0 0 0 0 0 0;} @font-face 	{font-family:Verdana; 	panose-1:2 11 6 4 3 5 4 4 2 4; 	mso-font-charset:0; 	mso-generic-font-family:swiss; 	mso-font-pitch:variable; 	mso-font-signature:536871559 0 0 0 415 0;} @font-face 	{font-family:&quot;\@新細明體&quot;; 	panose-1:2 2 3 0 0 0 0 0 0 0; 	mso-font-charset:136; 	mso-generic-font-family:roman; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 22 0 1048577 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-unhide:no; 	mso-style-qformat:yes; 	mso-style-parent:&quot;&quot;; 	margin-top:0cm; 	margin-right:0cm; 	margin-bottom:10.0pt; 	margin-left:0cm; 	line-height:115%; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	mso-bidi-font-size:11.0pt; 	font-family:&quot;Verdana&quot;,&quot;sans-serif&quot;; 	mso-fareast-font-family:新細明體; 	mso-bidi-font-family:&quot;Times New Roman&quot;; 	mso-fareast-language:EN-US;} .MsoChpDefault 	{mso-style-type:export-only; 	mso-default-props:yes; 	font-size:10.0pt; 	mso-ansi-font-size:10.0pt; 	mso-bidi-font-size:10.0pt; 	mso-ascii-font-family:&quot;Times New Roman&quot;; 	mso-fareast-font-family:新細明體; 	mso-hansi-font-family:&quot;Times New Roman&quot;; 	mso-font-kerning:0pt;}  /* Page Definitions */  @page 	{mso-page-border-surround-header:no; 	mso-page-border-surround-footer:no;} @page Section1 	{size:612.0pt 792.0pt; 	margin:72.0pt 90.0pt 72.0pt 90.0pt; 	mso-header-margin:36.0pt; 	mso-footer-margin:36.0pt; 	mso-paper-source:0;} div.Section1 	{page:Section1;} --&gt; 
&lt;/style&gt;  &lt;br /&gt;
&lt;div class=&quot;MsoNormal&quot; face=&quot;arial&quot; style=&quot;font-family: arial;&quot;&gt;&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;Orienting the Cube&lt;/span&gt;&lt;/b&gt;&lt;span lang=&quot;EN-US&quot;&gt; –&lt;/span&gt;&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt; &lt;/span&gt;&lt;/b&gt;&lt;span lang=&quot;EN-US&quot;&gt;Touch one finger and move it in the direction you want the cube to rotate&lt;/span&gt;&lt;/div&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2BvnIWl0uUC7X7r3_N5HR4gMTykPmZ5F8GtlzRDXjHTBFWXl2-R78b6V3pJKQO_y4KLVUeKAdfq4A3F28PyHgBjw3xzhLambwDG3AmJ2VhuunERuFh7qNPi0ER5se1zRxbvWTsgpTKVhl/s1600/1.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; style=&quot;font-family: arial;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5495528202649181026&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2BvnIWl0uUC7X7r3_N5HR4gMTykPmZ5F8GtlzRDXjHTBFWXl2-R78b6V3pJKQO_y4KLVUeKAdfq4A3F28PyHgBjw3xzhLambwDG3AmJ2VhuunERuFh7qNPi0ER5se1zRxbvWTsgpTKVhl/s400/1.png&quot; style=&quot;cursor: pointer; height: 113px; width: 393px;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;                            [圖 1] Orienting the cube&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;meta content=&quot;text/html; charset=utf-8&quot; http-equiv=&quot;Content-Type&quot;&gt;&lt;/meta&gt;&lt;meta content=&quot;Word.Document&quot; name=&quot;ProgId&quot;&gt;&lt;/meta&gt;&lt;meta content=&quot;Microsoft Word 12&quot; name=&quot;Generator&quot;&gt;&lt;/meta&gt;&lt;meta content=&quot;Microsoft Word 12&quot; name=&quot;Originator&quot;&gt;&lt;/meta&gt;&lt;link href=&quot;file:///C:%5CDOCUME%7E1%5C97100634%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_filelist.xml&quot; rel=&quot;File-List&quot; style=&quot;font-family: arial;&quot;&gt;&lt;/link&gt;&lt;link href=&quot;file:///C:%5CDOCUME%7E1%5C97100634%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_themedata.thmx&quot; rel=&quot;themeData&quot; style=&quot;font-family: arial;&quot;&gt;&lt;/link&gt;&lt;link href=&quot;file:///C:%5CDOCUME%7E1%5C97100634%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_colorschememapping.xml&quot; rel=&quot;colorSchemeMapping&quot; style=&quot;font-family: arial;&quot;&gt;&lt;/link&gt;&lt;style&gt;
 &lt;!--  /* Font Definitions */  @font-face 	{font-family:新細明體; 	panose-1:2 2 3 0 0 0 0 0 0 0; 	mso-font-alt:PMingLiU; 	mso-font-charset:136; 	mso-generic-font-family:roman; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 22 0 1048577 0;} @font-face 	{font-family:&quot;Cambria Math&quot;; 	panose-1:2 4 5 3 5 4 6 3 2 4; 	mso-font-charset:1; 	mso-generic-font-family:roman; 	mso-font-format:other; 	mso-font-pitch:variable; 	mso-font-signature:0 0 0 0 0 0;} @font-face 	{font-family:Verdana; 	panose-1:2 11 6 4 3 5 4 4 2 4; 	mso-font-charset:0; 	mso-generic-font-family:swiss; 	mso-font-pitch:variable; 	mso-font-signature:536871559 0 0 0 415 0;} @font-face 	{font-family:&quot;\@新細明體&quot;; 	panose-1:2 2 3 0 0 0 0 0 0 0; 	mso-font-charset:136; 	mso-generic-font-family:roman; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 22 0 1048577 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-unhide:no; 	mso-style-qformat:yes; 	mso-style-parent:&quot;&quot;; 	margin-top:0cm; 	margin-right:0cm; 	margin-bottom:10.0pt; 	margin-left:0cm; 	line-height:115%; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	mso-bidi-font-size:11.0pt; 	font-family:&quot;Verdana&quot;,&quot;sans-serif&quot;; 	mso-fareast-font-family:新細明體; 	mso-bidi-font-family:&quot;Times New Roman&quot;; 	mso-fareast-language:EN-US;} .MsoChpDefault 	{mso-style-type:export-only; 	mso-default-props:yes; 	font-size:10.0pt; 	mso-ansi-font-size:10.0pt; 	mso-bidi-font-size:10.0pt; 	mso-ascii-font-family:&quot;Times New Roman&quot;; 	mso-fareast-font-family:新細明體; 	mso-hansi-font-family:&quot;Times New Roman&quot;; 	mso-font-kerning:0pt;}  /* Page Definitions */  @page 	{mso-page-border-surround-header:no; 	mso-page-border-surround-footer:no;} @page Section1 	{size:612.0pt 792.0pt; 	margin:72.0pt 90.0pt 72.0pt 90.0pt; 	mso-header-margin:36.0pt; 	mso-footer-margin:36.0pt; 	mso-paper-source:0;} div.Section1 	{page:Section1;} --&gt; 
&lt;/style&gt;&lt;b style=&quot;font-family: arial;&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 10pt; line-height: 115%;&quot;&gt;Rotating a Cube Section&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 10pt; line-height: 115%;&quot;&gt; - &lt;/span&gt;&lt;/b&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: arial; font-size: 10pt; line-height: 115%;&quot;&gt;Touch one finger and move it inside the section you wish to move, and then move it in the direction you want to rotate the section&lt;/span&gt;&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXFikKKwAHghtSvxhXZsV7klkUlqinZIUSwn7W7R7GFHx7fEcz2t9zrBOsw_93S_qqDJcJQtAXxzfWSfzGEec05p8jzdzqgS-0tdz7dmrggdiuqBjkcUegIN3d0_OsS-_jkWPRIdgKFTqP/s1600/2.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; style=&quot;font-family: arial;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5495529439157419570&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXFikKKwAHghtSvxhXZsV7klkUlqinZIUSwn7W7R7GFHx7fEcz2t9zrBOsw_93S_qqDJcJQtAXxzfWSfzGEec05p8jzdzqgS-0tdz7dmrggdiuqBjkcUegIN3d0_OsS-_jkWPRIdgKFTqP/s400/2.png&quot; style=&quot;cursor: pointer; height: 120px; width: 400px;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;                              [圖 2] Rotating a cube section&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;meta content=&quot;text/html; charset=utf-8&quot; http-equiv=&quot;Content-Type&quot;&gt;&lt;/meta&gt;&lt;meta content=&quot;Word.Document&quot; name=&quot;ProgId&quot;&gt;&lt;/meta&gt;&lt;meta content=&quot;Microsoft Word 12&quot; name=&quot;Generator&quot;&gt;&lt;/meta&gt;&lt;meta content=&quot;Microsoft Word 12&quot; name=&quot;Originator&quot;&gt;&lt;/meta&gt;&lt;link href=&quot;file:///C:%5CDOCUME%7E1%5C97100634%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_filelist.xml&quot; rel=&quot;File-List&quot; style=&quot;font-family: arial;&quot;&gt;&lt;/link&gt;&lt;link href=&quot;file:///C:%5CDOCUME%7E1%5C97100634%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_themedata.thmx&quot; rel=&quot;themeData&quot; style=&quot;font-family: arial;&quot;&gt;&lt;/link&gt;&lt;link href=&quot;file:///C:%5CDOCUME%7E1%5C97100634%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_colorschememapping.xml&quot; rel=&quot;colorSchemeMapping&quot; style=&quot;font-family: arial;&quot;&gt;&lt;/link&gt;&lt;style&gt;
 &lt;!--  /* Font Definitions */  @font-face 	{font-family:新細明體; 	panose-1:2 2 3 0 0 0 0 0 0 0; 	mso-font-alt:PMingLiU; 	mso-font-charset:136; 	mso-generic-font-family:roman; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 22 0 1048577 0;} @font-face 	{font-family:&quot;Cambria Math&quot;; 	panose-1:2 4 5 3 5 4 6 3 2 4; 	mso-font-charset:1; 	mso-generic-font-family:roman; 	mso-font-format:other; 	mso-font-pitch:variable; 	mso-font-signature:0 0 0 0 0 0;} @font-face 	{font-family:Verdana; 	panose-1:2 11 6 4 3 5 4 4 2 4; 	mso-font-charset:0; 	mso-generic-font-family:swiss; 	mso-font-pitch:variable; 	mso-font-signature:536871559 0 0 0 415 0;} @font-face 	{font-family:&quot;\@新細明體&quot;; 	panose-1:2 2 3 0 0 0 0 0 0 0; 	mso-font-charset:136; 	mso-generic-font-family:roman; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 22 0 1048577 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-unhide:no; 	mso-style-qformat:yes; 	mso-style-parent:&quot;&quot;; 	margin-top:0cm; 	margin-right:0cm; 	margin-bottom:10.0pt; 	margin-left:0cm; 	line-height:115%; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	mso-bidi-font-size:11.0pt; 	font-family:&quot;Verdana&quot;,&quot;sans-serif&quot;; 	mso-fareast-font-family:新細明體; 	mso-bidi-font-family:&quot;Times New Roman&quot;; 	mso-fareast-language:EN-US;} .MsoChpDefault 	{mso-style-type:export-only; 	mso-default-props:yes; 	font-size:10.0pt; 	mso-ansi-font-size:10.0pt; 	mso-bidi-font-size:10.0pt; 	mso-ascii-font-family:&quot;Times New Roman&quot;; 	mso-fareast-font-family:新細明體; 	mso-hansi-font-family:&quot;Times New Roman&quot;; 	mso-font-kerning:0pt;}  /* Page Definitions */  @page 	{mso-page-border-surround-header:no; 	mso-page-border-surround-footer:no;} @page Section1 	{size:612.0pt 792.0pt; 	margin:72.0pt 90.0pt 72.0pt 90.0pt; 	mso-header-margin:36.0pt; 	mso-footer-margin:36.0pt; 	mso-paper-source:0;} div.Section1 	{page:Section1;} --&gt; 
&lt;/style&gt;&lt;b style=&quot;font-family: arial;&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 10pt; line-height: 115%;&quot;&gt;Zoom&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 10pt; line-height: 115%;&quot;&gt; In - &lt;/span&gt;&lt;/b&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: arial; font-size: 10pt; line-height: 115%;&quot;&gt;Touch two fingers and move them farther apart.&lt;/span&gt;&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqx1Y6FT4VINhM63_lHCx14UPN_NFqQeK_-dTAaGMUqrRlPufEUtrlmtHepw_FUqCcw7ype28ml-DlIP0z-0fabYN01nJnAu7oAtmCJT3N5IeJZt-pXFRtNDkE5uyVCIraGHVRPMS-RV7l/s1600/3.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; style=&quot;font-family: arial;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5495529520850716498&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqx1Y6FT4VINhM63_lHCx14UPN_NFqQeK_-dTAaGMUqrRlPufEUtrlmtHepw_FUqCcw7ype28ml-DlIP0z-0fabYN01nJnAu7oAtmCJT3N5IeJZt-pXFRtNDkE5uyVCIraGHVRPMS-RV7l/s400/3.png&quot; style=&quot;cursor: pointer; height: 118px; width: 400px;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;                                &lt;span style=&quot;font-family: arial;&quot;&gt; [圖 3] Zoom in&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;meta content=&quot;text/html; charset=utf-8&quot; http-equiv=&quot;Content-Type&quot;&gt;&lt;/meta&gt;&lt;meta content=&quot;Word.Document&quot; name=&quot;ProgId&quot;&gt;&lt;/meta&gt;&lt;meta content=&quot;Microsoft Word 12&quot; name=&quot;Generator&quot;&gt;&lt;/meta&gt;&lt;meta content=&quot;Microsoft Word 12&quot; name=&quot;Originator&quot;&gt;&lt;/meta&gt;&lt;link href=&quot;file:///C:%5CDOCUME%7E1%5C97100634%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_filelist.xml&quot; rel=&quot;File-List&quot; style=&quot;font-family: arial;&quot;&gt;&lt;/link&gt;&lt;link href=&quot;file:///C:%5CDOCUME%7E1%5C97100634%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_themedata.thmx&quot; rel=&quot;themeData&quot; style=&quot;font-family: arial;&quot;&gt;&lt;/link&gt;&lt;link href=&quot;file:///C:%5CDOCUME%7E1%5C97100634%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_colorschememapping.xml&quot; rel=&quot;colorSchemeMapping&quot; style=&quot;font-family: arial;&quot;&gt;&lt;/link&gt;&lt;style&gt;
 &lt;!--  /* Font Definitions */  @font-face 	{font-family:新細明體; 	panose-1:2 2 3 0 0 0 0 0 0 0; 	mso-font-alt:PMingLiU; 	mso-font-charset:136; 	mso-generic-font-family:roman; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 22 0 1048577 0;} @font-face 	{font-family:&quot;Cambria Math&quot;; 	panose-1:2 4 5 3 5 4 6 3 2 4; 	mso-font-charset:1; 	mso-generic-font-family:roman; 	mso-font-format:other; 	mso-font-pitch:variable; 	mso-font-signature:0 0 0 0 0 0;} @font-face 	{font-family:Verdana; 	panose-1:2 11 6 4 3 5 4 4 2 4; 	mso-font-charset:0; 	mso-generic-font-family:swiss; 	mso-font-pitch:variable; 	mso-font-signature:536871559 0 0 0 415 0;} @font-face 	{font-family:&quot;\@新細明體&quot;; 	panose-1:2 2 3 0 0 0 0 0 0 0; 	mso-font-charset:136; 	mso-generic-font-family:roman; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 22 0 1048577 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-unhide:no; 	mso-style-qformat:yes; 	mso-style-parent:&quot;&quot;; 	margin-top:0cm; 	margin-right:0cm; 	margin-bottom:10.0pt; 	margin-left:0cm; 	line-height:115%; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	mso-bidi-font-size:11.0pt; 	font-family:&quot;Verdana&quot;,&quot;sans-serif&quot;; 	mso-fareast-font-family:新細明體; 	mso-bidi-font-family:&quot;Times New Roman&quot;; 	mso-fareast-language:EN-US;} .MsoChpDefault 	{mso-style-type:export-only; 	mso-default-props:yes; 	font-size:10.0pt; 	mso-ansi-font-size:10.0pt; 	mso-bidi-font-size:10.0pt; 	mso-ascii-font-family:&quot;Times New Roman&quot;; 	mso-fareast-font-family:新細明體; 	mso-hansi-font-family:&quot;Times New Roman&quot;; 	mso-font-kerning:0pt;}  /* Page Definitions */  @page 	{mso-page-border-surround-header:no; 	mso-page-border-surround-footer:no;} @page Section1 	{size:612.0pt 792.0pt; 	margin:72.0pt 90.0pt 72.0pt 90.0pt; 	mso-header-margin:36.0pt; 	mso-footer-margin:36.0pt; 	mso-paper-source:0;} div.Section1 	{page:Section1;} --&gt; 
&lt;/style&gt;&lt;b style=&quot;font-family: arial;&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 10pt; line-height: 115%;&quot;&gt;Zoom&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 10pt; line-height: 115%;&quot;&gt; Out - &lt;/span&gt;&lt;/b&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: arial; font-size: 10pt; line-height: 115%;&quot;&gt;Touch two fingers and move them closer apart&lt;/span&gt;&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhz9imlqd9o4ItybAHY6QkVWO6VmikP1XvoQ5_jhlya95vM5XzJnnWVksoTOo_1If5e8OXwAnbI3x1EGGnZSTU3XSZYsXFNCCFaD36Jq9MA9PGkmnpsFhCBhHyb2XG19eiHEm-YQqP7Fcde/s1600/4.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; style=&quot;font-family: arial;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5495529653643703538&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhz9imlqd9o4ItybAHY6QkVWO6VmikP1XvoQ5_jhlya95vM5XzJnnWVksoTOo_1If5e8OXwAnbI3x1EGGnZSTU3XSZYsXFNCCFaD36Jq9MA9PGkmnpsFhCBhHyb2XG19eiHEm-YQqP7Fcde/s400/4.png&quot; style=&quot;cursor: pointer; height: 121px; width: 400px;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;                               &lt;span style=&quot;font-family: arial;&quot;&gt;    [圖 4] Zoom out&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;meta content=&quot;text/html; charset=utf-8&quot; http-equiv=&quot;Content-Type&quot;&gt;&lt;/meta&gt;&lt;meta content=&quot;Word.Document&quot; name=&quot;ProgId&quot;&gt;&lt;/meta&gt;&lt;meta content=&quot;Microsoft Word 12&quot; name=&quot;Generator&quot;&gt;&lt;/meta&gt;&lt;meta content=&quot;Microsoft Word 12&quot; name=&quot;Originator&quot;&gt;&lt;/meta&gt;&lt;link href=&quot;file:///C:%5CDOCUME%7E1%5C97100634%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_filelist.xml&quot; rel=&quot;File-List&quot; style=&quot;font-family: arial;&quot;&gt;&lt;/link&gt;&lt;link href=&quot;file:///C:%5CDOCUME%7E1%5C97100634%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_themedata.thmx&quot; rel=&quot;themeData&quot; style=&quot;font-family: arial;&quot;&gt;&lt;/link&gt;&lt;link href=&quot;file:///C:%5CDOCUME%7E1%5C97100634%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_colorschememapping.xml&quot; rel=&quot;colorSchemeMapping&quot; style=&quot;font-family: arial;&quot;&gt;&lt;/link&gt;&lt;style&gt;
 &lt;!--  /* Font Definitions */  @font-face 	{font-family:新細明體; 	panose-1:2 2 3 0 0 0 0 0 0 0; 	mso-font-alt:PMingLiU; 	mso-font-charset:136; 	mso-generic-font-family:roman; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 22 0 1048577 0;} @font-face 	{font-family:&quot;Cambria Math&quot;; 	panose-1:2 4 5 3 5 4 6 3 2 4; 	mso-font-charset:1; 	mso-generic-font-family:roman; 	mso-font-format:other; 	mso-font-pitch:variable; 	mso-font-signature:0 0 0 0 0 0;} @font-face 	{font-family:Verdana; 	panose-1:2 11 6 4 3 5 4 4 2 4; 	mso-font-charset:0; 	mso-generic-font-family:swiss; 	mso-font-pitch:variable; 	mso-font-signature:536871559 0 0 0 415 0;} @font-face 	{font-family:&quot;\@新細明體&quot;; 	panose-1:2 2 3 0 0 0 0 0 0 0; 	mso-font-charset:136; 	mso-generic-font-family:roman; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 22 0 1048577 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-unhide:no; 	mso-style-qformat:yes; 	mso-style-parent:&quot;&quot;; 	margin-top:0cm; 	margin-right:0cm; 	margin-bottom:10.0pt; 	margin-left:0cm; 	line-height:115%; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	mso-bidi-font-size:11.0pt; 	font-family:&quot;Verdana&quot;,&quot;sans-serif&quot;; 	mso-fareast-font-family:新細明體; 	mso-bidi-font-family:&quot;Times New Roman&quot;; 	mso-fareast-language:EN-US;} .MsoChpDefault 	{mso-style-type:export-only; 	mso-default-props:yes; 	font-size:10.0pt; 	mso-ansi-font-size:10.0pt; 	mso-bidi-font-size:10.0pt; 	mso-ascii-font-family:&quot;Times New Roman&quot;; 	mso-fareast-font-family:新細明體; 	mso-hansi-font-family:&quot;Times New Roman&quot;; 	mso-font-kerning:0pt;}  /* Page Definitions */  @page 	{mso-page-border-surround-header:no; 	mso-page-border-surround-footer:no;} @page Section1 	{size:612.0pt 792.0pt; 	margin:72.0pt 90.0pt 72.0pt 90.0pt; 	mso-header-margin:36.0pt; 	mso-footer-margin:36.0pt; 	mso-paper-source:0;} div.Section1 	{page:Section1;} --&gt; 
&lt;/style&gt;&lt;b style=&quot;font-family: arial;&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 10pt; line-height: 115%;&quot;&gt;Resetting All Rotations&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 10pt; line-height: 115%;&quot;&gt; - &lt;/span&gt;&lt;/b&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: arial; font-size: 10pt; line-height: 115%;&quot;&gt;Touch two fingers and move them in the same direction, entire cube orientation can be reset&lt;/span&gt;&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0zPwWBsP5qIq84-RGnrFyNmwjtw9c36fygOFkkFJchhvurmdb_cx-q8fameOViy9Lox9DvL-uk2UVFsjZPH8WqXgpYURAkOGte5xFbAKfDtoaGIdQ6Z3geNuG2SUl1hjiX40IsjN_bvmD/s1600/5.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; style=&quot;font-family: arial;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5495531041426237298&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0zPwWBsP5qIq84-RGnrFyNmwjtw9c36fygOFkkFJchhvurmdb_cx-q8fameOViy9Lox9DvL-uk2UVFsjZPH8WqXgpYURAkOGte5xFbAKfDtoaGIdQ6Z3geNuG2SUl1hjiX40IsjN_bvmD/s400/5.png&quot; style=&quot;cursor: pointer; height: 115px; width: 400px;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;                               &lt;span style=&quot;font-family: arial;&quot;&gt;   [圖 5] &lt;/span&gt;&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: arial; font-size: 10pt; line-height: 115%;&quot;&gt;Resetting all rotations&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;meta content=&quot;text/html; charset=utf-8&quot; http-equiv=&quot;Content-Type&quot;&gt;&lt;/meta&gt;&lt;meta content=&quot;Word.Document&quot; name=&quot;ProgId&quot;&gt;&lt;/meta&gt;&lt;meta content=&quot;Microsoft Word 12&quot; name=&quot;Generator&quot;&gt;&lt;/meta&gt;&lt;meta content=&quot;Microsoft Word 12&quot; name=&quot;Originator&quot;&gt;&lt;/meta&gt;&lt;link href=&quot;file:///C:%5CDOCUME%7E1%5C97100634%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_filelist.xml&quot; rel=&quot;File-List&quot; style=&quot;font-family: arial;&quot;&gt;&lt;/link&gt;&lt;link href=&quot;file:///C:%5CDOCUME%7E1%5C97100634%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_themedata.thmx&quot; rel=&quot;themeData&quot; style=&quot;font-family: arial;&quot;&gt;&lt;/link&gt;&lt;link href=&quot;file:///C:%5CDOCUME%7E1%5C97100634%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_colorschememapping.xml&quot; rel=&quot;colorSchemeMapping&quot; style=&quot;font-family: arial;&quot;&gt;&lt;/link&gt;&lt;style&gt;
 &lt;!--  /* Font Definitions */  @font-face 	{font-family:新細明體; 	panose-1:2 2 3 0 0 0 0 0 0 0; 	mso-font-alt:PMingLiU; 	mso-font-charset:136; 	mso-generic-font-family:roman; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 22 0 1048577 0;} @font-face 	{font-family:&quot;Cambria Math&quot;; 	panose-1:2 4 5 3 5 4 6 3 2 4; 	mso-font-charset:1; 	mso-generic-font-family:roman; 	mso-font-format:other; 	mso-font-pitch:variable; 	mso-font-signature:0 0 0 0 0 0;} @font-face 	{font-family:Verdana; 	panose-1:2 11 6 4 3 5 4 4 2 4; 	mso-font-charset:0; 	mso-generic-font-family:swiss; 	mso-font-pitch:variable; 	mso-font-signature:536871559 0 0 0 415 0;} @font-face 	{font-family:&quot;\@新細明體&quot;; 	panose-1:2 2 3 0 0 0 0 0 0 0; 	mso-font-charset:136; 	mso-generic-font-family:roman; 	mso-font-pitch:variable; 	mso-font-signature:3 135135232 22 0 1048577 0;}  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-unhide:no; 	mso-style-qformat:yes; 	mso-style-parent:&quot;&quot;; 	margin-top:0cm; 	margin-right:0cm; 	margin-bottom:10.0pt; 	margin-left:0cm; 	line-height:115%; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	mso-bidi-font-size:11.0pt; 	font-family:&quot;Verdana&quot;,&quot;sans-serif&quot;; 	mso-fareast-font-family:新細明體; 	mso-bidi-font-family:&quot;Times New Roman&quot;; 	mso-fareast-language:EN-US;} .MsoChpDefault 	{mso-style-type:export-only; 	mso-default-props:yes; 	font-size:10.0pt; 	mso-ansi-font-size:10.0pt; 	mso-bidi-font-size:10.0pt; 	mso-ascii-font-family:&quot;Times New Roman&quot;; 	mso-fareast-font-family:新細明體; 	mso-hansi-font-family:&quot;Times New Roman&quot;; 	mso-font-kerning:0pt;}  /* Page Definitions */  @page 	{mso-page-border-surround-header:no; 	mso-page-border-surround-footer:no;} @page Section1 	{size:612.0pt 792.0pt; 	margin:72.0pt 90.0pt 72.0pt 90.0pt; 	mso-header-margin:36.0pt; 	mso-footer-margin:36.0pt; 	mso-paper-source:0;} div.Section1 	{page:Section1;} --&gt; 
&lt;/style&gt;&lt;b style=&quot;font-family: arial;&quot;&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 10pt; line-height: 115%;&quot;&gt;Scrambling the Cube&lt;/span&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-size: 10pt; line-height: 115%;&quot;&gt; - &lt;/span&gt;&lt;/b&gt;&lt;span lang=&quot;EN-US&quot; style=&quot;font-family: arial; font-size: 10pt; line-height: 115%;&quot;&gt;Touch two fingers and turn them in a circle to scramble the cube&lt;/span&gt;&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5xzs9jmpL8TP84pgupFIImi2WFFr8OLUkKCUzi9UbW36fT-PC2GyDmFoQn9fekn_HyVahQRtIcCSRyDEtLTLipGna_rvaKKnKh9icwGK_MHnWQt0NI5yFlnNTeiK7wO-6rsU8wduHqyXm/s1600/6.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; style=&quot;font-family: arial;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5495531116653582786&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5xzs9jmpL8TP84pgupFIImi2WFFr8OLUkKCUzi9UbW36fT-PC2GyDmFoQn9fekn_HyVahQRtIcCSRyDEtLTLipGna_rvaKKnKh9icwGK_MHnWQt0NI5yFlnNTeiK7wO-6rsU8wduHqyXm/s400/6.png&quot; style=&quot;cursor: pointer; height: 115px; width: 400px;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;                           &lt;span style=&quot;font-family: arial;&quot;&gt;     [圖 6] Scrambling the cube&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br style=&quot;font-family: arial;&quot; /&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/7031865648027614102/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2010/09/touch-game-rubiks-cube.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/7031865648027614102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/7031865648027614102'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2010/09/touch-game-rubiks-cube.html' title='Touch Game - Rubik&#39;s Cube'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2BvnIWl0uUC7X7r3_N5HR4gMTykPmZ5F8GtlzRDXjHTBFWXl2-R78b6V3pJKQO_y4KLVUeKAdfq4A3F28PyHgBjw3xzhLambwDG3AmJ2VhuunERuFh7qNPi0ER5se1zRxbvWTsgpTKVhl/s72-c/1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-2067555292116426348</id><published>2010-09-08T23:21:00.000-07:00</published><updated>2010-11-30T17:11:15.333-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="Programing"/><title type='text'>Callback Function</title><content type='html'>&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;b&gt;什麼是&lt;span lang=&quot;EN-US&quot;&gt;Callback function?&lt;/span&gt; &lt;/b&gt;&amp;nbsp;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;如果在程式中使用某個&lt;span lang=&quot;EN-US&quot;&gt;function, &lt;/span&gt;我們可稱作&lt;span lang=&quot;EN-US&quot;&gt;”call” function,&lt;/span&gt;這種行為是主動的&lt;span lang=&quot;EN-US&quot;&gt;, &amp;nbsp;&lt;/span&gt;而&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;callback function&lt;/span&gt;&lt;/b&gt;是被動的&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;也就是當特定事件發生時&lt;span lang=&quot;EN-US&quot;&gt;(&lt;/span&gt;例如觸控發生&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;或某手勢被偵測&lt;span lang=&quot;EN-US&quot;&gt;)&lt;/span&gt;,&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;callback function&lt;/span&gt;&lt;/b&gt;才會被呼叫&lt;span lang=&quot;EN-US&quot;&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;而&lt;b&gt;Callback&lt;/b&gt;在&lt;b&gt;C/C++&lt;/b&gt;實現的方式, 就是利用&lt;b&gt;function pointer(函式指標), &lt;/b&gt;例如A程式想要B程式發生某些事件時, 能通知A&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;程式&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;. 利用&lt;b&gt;Callback&lt;/b&gt;機制的話, A程式必須傳一個&lt;b&gt;function pointer&lt;/b&gt;給B&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;程式&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;,讓B&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;程式&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;可以使用這個&lt;b&gt;function pointer&lt;/b&gt;來通知A&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;程式&lt;/span&gt;&lt;span lang=&quot;EN-US&quot;&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;br /&gt;
&lt;b&gt;function pointer&lt;/b&gt;(函式指標)宣告的方式如下:&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;span style=&quot;background-color: #cc0000;&quot;&gt;&lt;span style=&quot;background-color: yellow; color: black;&quot;&gt;返回類型 (* 函式指標名稱) (參數列表);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: yellow;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
example:&lt;br /&gt;
&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; (* GetPointCallback)(&lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; x, &lt;span style=&quot;color: blue;&quot;&gt;int&lt;/span&gt; y);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;MsoListParagraph&quot; style=&quot;font-family: Arial,Helvetica,sans-serif; margin-left: 24pt; text-align: justify; text-indent: -24pt;&quot;&gt;&lt;span style=&quot;font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal;&quot;&gt;&lt;/span&gt;&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;Callback function&lt;/span&gt;的使用案例&lt;/b&gt;&lt;span lang=&quot;EN-US&quot;&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: justify;&quot;&gt;例如&lt;span lang=&quot;EN-US&quot;&gt;: &lt;/span&gt;我們在設計一個觸控繪圖的應用程式時&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;通常不會讓程式不斷地向系統要觸控點的資料&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;而是希望當系統偵測到觸控發生時&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;才會丟回觸控點的資料&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;而這個丟回觸控點的行為&lt;span lang=&quot;EN-US&quot;&gt;, &lt;/span&gt;就可以設計成&lt;span lang=&quot;EN-US&quot;&gt;&lt;b&gt;callback function&lt;/b&gt;. &lt;/span&gt;其示意圖如下所示&lt;span lang=&quot;EN-US&quot;&gt;:&lt;/span&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhomIkeVg3Aygt9aeHHaBD7YcppPF_ngxGHoybPmtuQRZqst_3-mCmXcA2tYsmyXPXo2-SHDLjdlahWrjKL5EJNbV1nYGSOelvRDSn77bBaO9EwdeRiGcTWlp8Mgi892vXAUtqaKN4Mi_rR/s1600/CALLBACK.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;628&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhomIkeVg3Aygt9aeHHaBD7YcppPF_ngxGHoybPmtuQRZqst_3-mCmXcA2tYsmyXPXo2-SHDLjdlahWrjKL5EJNbV1nYGSOelvRDSn77bBaO9EwdeRiGcTWlp8Mgi892vXAUtqaKN4Mi_rR/s640/CALLBACK.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;font-family: Arial,Helvetica,sans-serif; text-align: center;&quot;&gt;[圖 1] Touch Paint Callback function&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;MsoNormal&quot; style=&quot;text-align: justify;&quot;&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;b&gt;&lt;span lang=&quot;EN-US&quot;&gt;Callback function 範例程式&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;TouchAPI.h&lt;/div&gt;&lt;pre class=&quot;c++&quot; name=&quot;code&quot; style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;#ifdef  TOUCHAPI_EXPORTS
 #define TOUCH_API __declspec(dllexport)
#else
 #define TOUCH_API __declspec(dllimport)
#endif

// 定義觸控點的相關資訊
struct TouchPoint
{
 int X; 
 int Y; 
};

// 定義callback function的prototype
// CB_TOUCH_FUNC是一個pointer,指向具有一個TouchPoint類型,且回傳void型的函数
// 前面有個typedef,所以現在CB_TOUCH_FUNC是這種類型的别名
typedef void (_stdcall *CB_TOUCH_FUNC) (TouchPoint);

// 定義了一個RegisterCBTouchFunc的函式,可傳入一個具有CB_TOUCH_FUNC型別的callback function
TOUCH_API void RegisterCBTouchFunc(CB_TOUCH_FUNC callback);
&lt;/pre&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;TouchAPI.cpp&lt;/div&gt;&lt;pre class=&quot;c++&quot; name=&quot;code&quot; style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;#include &quot;stdafx.h&quot;
#include &quot;TouchAPI.h&quot;

void DetectTouchFromSystem(CB_TOUCH_FUNC callback)
{
    // 當系統取得touch資料時,
    // 就會呼叫一次pCB_TOUCH_FUNC參數所指到function一次
    TouchPoint tp;
    tp.X = 5;
    tp.Y = 10;
    callback(tp);
}

void RegisterCallbackTouchFunc(CB_TOUCH_FUNC callback)
{
 DetectTouchFromSystem(callback);
}
&lt;/pre&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;TouchPaint.cpp&lt;/div&gt;&lt;pre class=&quot;c++&quot; name=&quot;code&quot; style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;#include &quot;stdafx.h&quot;
#include &quot;conio.h&quot;
#include &quot;TouchAPI.h&quot;
 
// 定義了一個名為GetTouch的函式, 也就是callback函式
// 它的prototype必須與TouchAPI的CB_TOUCH_FUNC宣告一致
void _stdcall GetTouch(TouchPoint point)
{
 printf(&quot;x=%d, y=%d&quot;, point.X, point.Y);
}
 
int main(void)
{
    //註冊一個callback function
    RegisterCBTouchFunc(GetTouch);
    getch();
    return 0 ;
};
&lt;/pre&gt;&lt;br /&gt;
參考資料:&lt;br /&gt;
&lt;a href=&quot;http://www.dev.idv.tw/mediawiki/index.php/%E4%BD%95%E8%AC%82callback_function%EF%BC%9F&quot;&gt;何謂callback function&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://en.wikipedia.org/wiki/Callback_%28computer_science%29&quot;&gt;Callback (computer science)&lt;/a&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/2067555292116426348/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2010/09/callback-function.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/2067555292116426348'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/2067555292116426348'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2010/09/callback-function.html' title='Callback Function'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhomIkeVg3Aygt9aeHHaBD7YcppPF_ngxGHoybPmtuQRZqst_3-mCmXcA2tYsmyXPXo2-SHDLjdlahWrjKL5EJNbV1nYGSOelvRDSn77bBaO9EwdeRiGcTWlp8Mgi892vXAUtqaKN4Mi_rR/s72-c/CALLBACK.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-7827318884254656453</id><published>2010-05-30T08:17:00.000-07:00</published><updated>2010-05-30T11:00:38.491-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>C#記憶體管理</title><content type='html'>&lt;span style=&quot;font-family:arial;&quot;&gt;就&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;C++&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;或&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt; C#&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;程式而言, 記憶體的配置區域大致可分成三種&lt;/span&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;    &lt;span style=&quot;font-weight: bold;&quot;&gt;Global區域&lt;/span&gt; -若變數,函式或物件宣告成&lt;span style=&quot;color: rgb(51, 0, 153);&quot;&gt;static&lt;/span&gt;,將被配置到此區域內(這類的記憶體,常被稱為全域變數(global variable), 此區域內的所有資料為同一個process共用; Global區域內的記憶體生命週期會維持到程式結束後, 才會被釋放.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;    &lt;span style=&quot;font-weight: bold;&quot;&gt;Stack區域&lt;/span&gt; - Stack區域是用來儲存區域變數(local variable), 記憶體配置的生命週期受到其區塊範圍 (block scope) 的影響,當進入區塊時,會自動配置記憶體, 離開此區塊,記憶體也會被釋放.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;    &lt;span style=&quot;font-weight: bold;&quot;&gt;Heap區域&lt;/span&gt;- Heap是儲存動態配置的資料(例如:使用&lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt;new&lt;/span&gt;或&lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt;malloc&lt;/span&gt;()宣告), 此記憶體不會隨函式結束被釋放. 而且釋放方式會因不同程式語言而不同. 對於&lt;span style=&quot;font-weight: bold;&quot;&gt;C/C++&lt;/span&gt;這類的程式, 記憶體釋放需要由程式員手動釋放(例如: 使用&lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt;delete&lt;/span&gt; 或 &lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt;free&lt;/span&gt;()); 而 &lt;span style=&quot;font-weight: bold;&quot;&gt;Java&lt;/span&gt; 與 &lt;span style=&quot;font-weight: bold;&quot;&gt;C# &lt;/span&gt;程式, 記憶體釋放則由 &lt;span style=&quot;font-weight: bold;&quot;&gt;VM&lt;/span&gt;(虛擬機)自動作處理, 也就是&lt;a href=&quot;http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29&quot;&gt;Garbage Collection&lt;/a&gt;的機制.&lt;span style=&quot;text-decoration: underline;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;如果&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;記憶體的釋放&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;是交由 &lt;span style=&quot;font-weight: bold;&quot;&gt;GC&lt;/span&gt; 負責控制, 程式員就不必擔心記憶體遺失或使用到錯誤記憶體等問題(可參考&lt;a href=&quot;http://johnniebooks.blogspot.com/2010/05/how-to-detect-memory-leak.html&quot;&gt;How to detect memory leak&lt;/a&gt;), 既然&lt;span style=&quot;font-weight: bold;&quot;&gt;GC&lt;/span&gt;那麼方便,  那我們&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;先來了解&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;GC&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;是如何運作?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;GC&lt;/span&gt; 會追蹤 (tracing) 所有活著的物件, 如果不是活著的物件, 就會被標成 &lt;span style=&quot;font-weight: bold;&quot;&gt;GC&lt;/span&gt; 該清除的垃圾.&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;若變數為數值型別, 當變數超出有效範圍時, &lt;span style=&quot;font-weight: bold;&quot;&gt;CLR&lt;/span&gt;會直接回收它在&lt;span style=&quot;font-weight: bold;&quot;&gt;Stack&lt;/span&gt;上所佔用的空間, 若變數為參考型別, &lt;span style=&quot;font-weight: bold;&quot;&gt;CLR&lt;/span&gt;會先回收它在&lt;span style=&quot;font-weight: bold;&quot;&gt;Stack&lt;/span&gt;上佔用的空間, 再將&lt;span style=&quot;font-weight: bold;&quot;&gt;Heap&lt;/span&gt;上的空間視為garbage, 等待&lt;span style=&quot;font-weight: bold;&quot;&gt;GC&lt;/span&gt;回收. 若參考型別的變數在其有效範圍內重新初始化, 則原先所指向的物件亦會被視為garbage.&lt;br /&gt;然而, 被視為garbage的物件, 並不會馬上就被&lt;span style=&quot;font-weight: bold;&quot;&gt;GC&lt;/span&gt;回收, 而是根據&lt;span style=&quot;font-weight: bold;&quot;&gt;GC&lt;/span&gt;內的演算法, 依變數被判定的generation而有不同.&lt;/span&gt; &lt;span style=&quot;font-family:arial;&quot;&gt;下面為&lt;span style=&quot;font-weight: bold;&quot;&gt;GC&lt;/span&gt;的測試&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;程式:&lt;br /&gt;&lt;br /&gt;C#程式碼 :&lt;br /&gt;&lt;pre class=&quot;c++&quot; name=&quot;code&quot;&gt;&lt;br /&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt; Console.WriteLine(&quot;程式開始&quot;);&lt;br /&gt; MyClass myClass = new MyClass();&lt;br /&gt; myClass = null;&lt;br /&gt; Console.WriteLine(&quot;程式結束&quot;);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;執行結果, &lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;GC&lt;/span&gt;會在程式結束後自動作記憶體回收&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span&gt;:&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0Rq4pfXaCZsI5uLc10xZcN5u-JCvw-Aaow2xTevZEGanwRSvtqWceYlCzLqmbpO6cWDXdlGgqnN_dd_s_jK5ng2lEpMHizsFpnE9lQ9U6YKfjAaMpEgjvXp5EBdaWtRPBnZFu_2vec2Yx/s1600/GC1.jpg&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 328px; height: 161px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0Rq4pfXaCZsI5uLc10xZcN5u-JCvw-Aaow2xTevZEGanwRSvtqWceYlCzLqmbpO6cWDXdlGgqnN_dd_s_jK5ng2lEpMHizsFpnE9lQ9U6YKfjAaMpEgjvXp5EBdaWtRPBnZFu_2vec2Yx/s400/GC1.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5477107225533040258&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;[圖1] GC自動回收記憶體&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt; &lt;div style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;雖然&lt;span style=&quot;font-weight: bold;&quot;&gt;GC&lt;/span&gt;會幫程式人員自動清理記憶體, 但還是有可能發生, 要及時釋放某些記憶體(unmanged object)或資源時, 例如視窗控制代碼 (HWND), 資料庫連接等時, 該怎麼做?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; &lt;/div&gt; &lt;span style=&quot;font-family:arial;&quot;&gt;C# 提供三種方式, &lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;讓程式人員可手動釋放記憶體或資源:&lt;/span&gt; &lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;&lt;br /&gt;(1) 呼叫&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/xe0c2357%28VS.80%29.aspx&quot;&gt;GC.Collect()&lt;/a&gt;&lt;/span&gt; &lt;div style=&quot;text-align: justify;&quot;&gt;&lt;div face=&quot;arial&quot; style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;使用&lt;/span&gt;&lt;span style=&quot;font-weight: bold; font-family: arial;&quot;&gt;GC.Collect()&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;可強制系統嘗試回收可用記憶體的最大量. 但一般來說. 應該盡量避免呼叫&lt;/span&gt;&lt;span style=&quot;font-weight: bold; font-family: arial;&quot;&gt;GC.Collect()&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;來回收記憶體, 因為在記憶體回收行程執行回收之前，它會暫停所有目前正在執行的執行緒. 如果在不必要的情況下呼叫 &lt;/span&gt;&lt;span style=&quot;font-weight: bold; font-family: arial;&quot;&gt;GC.Collect()&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;太過頻繁的話, 反而會造成效能上的問題. 此方法使用範例如下&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;C#檔&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;  Console.WriteLine(&quot;程式開始&quot;);&lt;br /&gt;  MyClass myClass = new MyClass();&lt;br /&gt;  myClass = null;&lt;br /&gt;  GC.Collect();&lt;br /&gt;  //因為GC回收時是在另一個thread&lt;br /&gt;  //所以使用WaitForPendingFinalizers等到確實回收後再繼續執行&lt;br /&gt;   GC.WaitForPendingFinalizers();&lt;br /&gt;   Console.WriteLine(&quot;程式結束&quot;);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;執行結果&lt;br /&gt;&lt;/span&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMXiUzHq1Ezo7r225WknUgSqOzrlg67CkousE_LvV5GRry03EClWIU0cULkDcerMu9fwTbIntIu7Z5Q_UuRHpBKrIgthkupzAruhI1XiXlfLRJwGTX-4Hoi1tO7zh6VqM2PAPsYFq-JIbN/s1600/G3.jpg&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 262px; height: 130px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMXiUzHq1Ezo7r225WknUgSqOzrlg67CkousE_LvV5GRry03EClWIU0cULkDcerMu9fwTbIntIu7Z5Q_UuRHpBKrIgthkupzAruhI1XiXlfLRJwGTX-4Hoi1tO7zh6VqM2PAPsYFq-JIbN/s400/G3.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5477109874862377618&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;[圖2] &lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;使用GC.Collect()&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;強制回收記憶體&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;/div&gt; &lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;(2) 實作 &lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.object.finalize%28VS.95%29.aspx&quot;&gt;Finalize&lt;/a&gt;&lt;/span&gt; &lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;實作 &lt;/span&gt;&lt;b style=&quot;font-family: arial;&quot;&gt;Finalize&lt;/b&gt;&lt;span style=&quot;font-family:arial;&quot;&gt; 方法, 如同C++中的解構函式語法, &lt;/span&gt;程式碼範例如下:&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;C#檔&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;public class MyClass&lt;br /&gt;{&lt;br /&gt;  UnmanagedResource unmRes ;&lt;br /&gt;&lt;br /&gt;  public MyClass()&lt;br /&gt;  {&lt;br /&gt;      Console.WriteLine(&quot;建構 MyClass&quot;);&lt;br /&gt;      unmRes = new UnmanagedResource();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  ~MyClass()&lt;br /&gt;  {&lt;br /&gt;      /// 釋放unmanaged資源&lt;br /&gt;      unmRes.Release();&lt;br /&gt;&lt;br /&gt;      Console.WriteLine(&quot;解構 MyClass&quot;);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;執行結果:&lt;br /&gt;&lt;/span&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIYEnxhw8WyOHYpnojGzkWz_XMRvqtJ3cF0oiFw1_UxaMuNYdFE4qgkZ8f2qsJGS3_FOxZhRS7FwuO6B8qij-KUjH7RRaB9Vk3DeS3BuoPgcrQB4TnjZWHrww5h115VeqfL5lzcw1hfdmc/s1600/GC2.jpg&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 208px; height: 135px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIYEnxhw8WyOHYpnojGzkWz_XMRvqtJ3cF0oiFw1_UxaMuNYdFE4qgkZ8f2qsJGS3_FOxZhRS7FwuO6B8qij-KUjH7RRaB9Vk3DeS3BuoPgcrQB4TnjZWHrww5h115VeqfL5lzcw1hfdmc/s400/GC2.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5477107230552974594&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;[圖3] &lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;利用&lt;/span&gt;&lt;b style=&quot;font-family: arial;&quot;&gt;Finalize&lt;/b&gt;&lt;span style=&quot;font-family:arial;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;回收記憶體&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b style=&quot;font-family: arial; color: rgb(0, 0, 0);&quot;&gt;Finalize&lt;/b&gt;&lt;span style=&quot;color: rgb(0, 0, 0);font-family:arial;&quot; &gt; 雖&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);font-family:arial;&quot; &gt;可用於釋放一些記憶體, &lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);font-family:arial;&quot; &gt;但執行的時機由&lt;span style=&quot;font-weight: bold;&quot;&gt;GC&lt;/span&gt;控制, &lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);font-family:arial;&quot; &gt;因此我們無法&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);font-family:arial;&quot; &gt;預期&lt;span style=&quot;font-weight: bold;&quot;&gt;Finalize()&lt;/span&gt;究竟會何時會被呼叫&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);font-family:arial;&quot; &gt;, 這樣如果我們有急迫的資源必須釋放,這時候怎麼辦?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;(3)使用&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/fs2xkftw%28VS.80%29.aspx&quot;&gt;Dispose&lt;/a&gt;&lt;/span&gt; &lt;div style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;若要明確地釋放資源和物件, 使用&lt;span style=&quot;font-weight: bold;&quot;&gt;Dispose&lt;/span&gt;將是最好的方式&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;.程式員呼叫的方式如下:&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 0);font-family:arial;&quot; &gt;&lt;span style=&quot;font-family:arial;&quot;&gt;明確地呼叫&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: rgb(0, 0, 0);font-family:arial;&quot; &gt;Dispose()&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;使用&lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt;using&lt;/span&gt;陳述式, 在離開&lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt;using&lt;/span&gt;區塊時, 其&lt;span style=&quot;font-weight: bold;&quot;&gt;Dispose()&lt;/span&gt;會被明確地呼叫&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt; &lt;span style=&quot;font-family:arial;&quot;&gt;請注意, 使用 &lt;span style=&quot;font-weight: bold;&quot;&gt;Dispose &lt;/span&gt;雖然可以讓程式員明確地控制, 但也不能少用 &lt;span style=&quot;font-weight: bold;&quot;&gt;Finalize&lt;/span&gt; 方法. 因為當程式員呼叫 &lt;span style=&quot;font-weight: bold;&quot;&gt;Dispose&lt;/span&gt; 失敗, 則 &lt;span style=&quot;font-weight: bold;&quot;&gt;Finalize &lt;/span&gt;會提供備份, 以避免資源沒被釋放掉, 相關程式碼如下:&lt;br /&gt;&lt;br /&gt;C#檔:&lt;br /&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;&lt;br /&gt;public class Memory : IDisposable&lt;br /&gt;{&lt;br /&gt;  private bool isDisposed = false;&lt;br /&gt;&lt;br /&gt;  public Memory()&lt;br /&gt;  {&lt;br /&gt;      Console.WriteLine(&quot;建構 Memory&quot;);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  ~Memory()&lt;br /&gt;  {&lt;br /&gt;      Dispose(false);&lt;br /&gt;      Console.WriteLine(&quot;解構 Memory&quot;);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  protected void Dispose(bool Diposing)&lt;br /&gt;  {&lt;br /&gt;      if (!isDisposed)&lt;br /&gt;      {&lt;br /&gt;          if (Diposing)&lt;br /&gt;          {&lt;br /&gt;              //Clean Up managed resources&lt;br /&gt;          }&lt;br /&gt;          //Clean up unmanaged resources&lt;br /&gt;      }&lt;br /&gt;      isDisposed = true;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void Dispose()&lt;br /&gt;  {&lt;br /&gt;      Console.WriteLine(&quot;Dispose called!&quot;);&lt;br /&gt;      Dispose(true);&lt;br /&gt;      //藉由呼叫 GC.SuppressFinalize 方法來避免 Finalize 方法的執行&lt;br /&gt;      GC.SuppressFinalize(this);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;執行結果:&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;Console.WriteLine(&quot;程式開始&quot;);&lt;br /&gt;using (Memory memory = new Memory())&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;Console.WriteLine(&quot;程式結束&quot;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMWvRJnGD2rkenhKboh7jswskJPDQWHfi9cUq2McQdPUGbsZfxWaiQFvaCTR5UrfQ__4VhEKOhyphenhyphen_uu3xSsqAlG7dwEikIXsGScnfibsw1bKxCybfLJvQBqmEQCsw5z4oqf55M7d_2P3hqe/s1600/G4.jpg&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 289px; height: 137px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMWvRJnGD2rkenhKboh7jswskJPDQWHfi9cUq2McQdPUGbsZfxWaiQFvaCTR5UrfQ__4VhEKOhyphenhyphen_uu3xSsqAlG7dwEikIXsGScnfibsw1bKxCybfLJvQBqmEQCsw5z4oqf55M7d_2P3hqe/s400/G4.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5477113445436354882&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;[圖4] &lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;利用&lt;/span&gt;Dispose&lt;span style=&quot;font-family:arial;&quot;&gt;回收記憶體&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;   &lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;結 論&lt;/span&gt; :&lt;/span&gt; &lt;ul style=&quot;text-align: justify;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;    &lt;span style=&quot;font-weight: bold;&quot;&gt;GC&lt;/span&gt;會自動管理Managed resource, 所以不需要程式員煩惱, 除非有用到 unmanaged resource 並需要釋放, 才會用&lt;span style=&quot;font-weight: bold;&quot;&gt;Dispose/Finalize&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;    &lt;span style=&quot;font-weight: bold;&quot;&gt;Finalize() &lt;/span&gt;是交給 &lt;span style=&quot;font-weight: bold;&quot;&gt;GC &lt;/span&gt;安排時間去處理&lt;span style=&quot;font-weight: bold;&quot;&gt;, Dispose() &lt;/span&gt;則讓使用者決定使用的時機&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;    除非必要時機, 否則不建議呼叫&lt;span style=&quot;font-weight: bold;&quot;&gt;GC&lt;/span&gt;類別的&lt;span style=&quot;font-weight: bold;&quot;&gt;Collect&lt;/span&gt;方法來強制回收記憶體&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt; &lt;span style=&quot;font-family:arial;&quot;&gt;參考文章:&lt;/span&gt; &lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/0xy59wtx%28VS.80%29.aspx&quot;&gt;記憶體回收&lt;/a&gt;&lt;/span&gt; &lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/dd229208.aspx&quot;&gt;.NET 的自動記憶體管理&lt;/a&gt;&lt;/span&gt; &lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;a href=&quot;http://www.wretch.cc/blog/cwz0205/18054344&quot;&gt;C# garbage collection 筆記&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;a href=&quot;http://neo_lin_42.blog.ithome.com.tw/post/620/6564&quot;&gt;.NET Framework記憶體回收機制&lt;/a&gt;&lt;/span&gt; &lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;a href=&quot;http://sedc.pixnet.net/blog/post/14184015&quot;&gt;C# - 資源釋放的觀念整理&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/b1yfkh5e%28VS.80%29.aspx&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;實作 Finalize 和 Dispose 以清除 Unmanaged 資源&lt;/span&gt;&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/7827318884254656453/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2010/05/c.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/7827318884254656453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/7827318884254656453'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2010/05/c.html' title='C#記憶體管理'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0Rq4pfXaCZsI5uLc10xZcN5u-JCvw-Aaow2xTevZEGanwRSvtqWceYlCzLqmbpO6cWDXdlGgqnN_dd_s_jK5ng2lEpMHizsFpnE9lQ9U6YKfjAaMpEgjvXp5EBdaWtRPBnZFu_2vec2Yx/s72-c/GC1.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-563973976738554604</id><published>2010-05-28T08:50:00.000-07:00</published><updated>2010-05-28T10:19:12.217-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><title type='text'>How to detect memory leak</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;記憶體管理對C/C++程式開發是個很重要的議題, 在程式中配置記憶體很容易, 但什麼時間點該釋放記憶體, 就是個很麻煩的問題. 如果配置的記憶體不作釋放, 就會導致系統永遠無法取得那塊記憶體,而造成記憶體遺漏(&lt;a href=&quot;http://en.wikipedia.org/wiki/Memory_leak&quot;&gt;Memory Leak)&lt;/a&gt;, 若釋放不該釋放的記憶體, 程式運行到一半找不到對應的位址時, 也會造成程式當掉.上述的這些問題, 常常會發生在C/C++的初學者, 或已經習慣&lt;/span&gt;自動記憶體管理&lt;span style=&quot;font-family:arial;&quot;&gt;的程式員身上.&lt;br /&gt;&lt;br /&gt;下面的步驟說明如何在C++的程式中, 偵測memory leak的發生.&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;引用下列標頭檔   &lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;  &lt;span style=&quot;font-family:arial;&quot;&gt;      &lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt;#define&lt;/span&gt; _CRTDBG_MAP_ALLOC&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;         &lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt; #include&lt;/span&gt; &amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;         &lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt; #include&lt;/span&gt; &amp;lt;crtdbg.h&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;輸出記憶體洩漏資訊&lt;pre&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;_CrtDumpMemoryLeaks();&lt;/span&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;在Visual Studio中選擇Debug模式然後執行, &lt;/span&gt;若程式中有發生記憶體遺漏, 其相關資訊將出現在&lt;span style=&quot;font-family:arial;&quot;&gt;輸出視窗中.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;下面的程式範例中, 我們利用&lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt;new&lt;/span&gt;配置了一個物件記憶體, 且不將其記憶體作釋放:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;c++&quot; name=&quot;code&quot;&gt;&lt;br /&gt;#define _CRTDBG_MAP_ALLOC&lt;br /&gt;&lt;br /&gt;#include &quot;stdafx.h&quot;&lt;br /&gt;#include &quot;MyClass.h&quot;&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#include &amp;lt;crtdbg.h&amp;gt;&lt;br /&gt;&lt;br /&gt;int _tmain(int argc, _TCHAR* argv[])&lt;br /&gt;{&lt;br /&gt;CMyClass* pClass = new CMyClass();&lt;br /&gt;//delete pClass;&lt;br /&gt;pClass = NULL;&lt;br /&gt;_CrtDumpMemoryLeaks();&lt;br /&gt;&lt;br /&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;在輸出視窗中我們將觀看到記憶體遺漏的資訊如下:&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;Detected memory leaks!&lt;br /&gt;Dumping objects -&gt;&lt;br /&gt;{86} normal block at 0x00397D98, 1 bytes long.&lt;br /&gt; Data: &lt; &gt; CD&lt;br /&gt;Object dump complete.&lt;br /&gt;The program &#39;[848] MemoryLeakTest.exe: Native&#39; has exited with code 0 (0x0).&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;參考文章:&lt;/span&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/e5ewb1h3%28VS.80%29.aspx&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;啟用記憶體遺漏偵測&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href=&quot;http://askalee.blogspot.com/2007/04/visual-cmemory-leak.html&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;在Visual C++使用內建功能偵測memory leak&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/563973976738554604/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2010/05/how-to-detect-memory-leak.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/563973976738554604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/563973976738554604'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2010/05/how-to-detect-memory-leak.html' title='How to detect memory leak'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-4381655300442225312</id><published>2010-04-15T18:28:00.001-07:00</published><updated>2010-05-25T18:55:39.173-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Game"/><category scheme="http://www.blogger.com/atom/ns#" term="Silverlight"/><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><title type='text'>Game Loop  Compare- DispacterTimer, Storyboard, Composition.Rendering</title><content type='html'>&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Game_programming&quot;&gt;Game Loop&lt;/a&gt; 對寫遊戲來說是一個很重要的步驟, 通常我們會將一些不需長時間且不用大量計算的事情, 放在Game Loop裡面去作, 例如:碰撞偵測, 動畫撥放, 更新繪圖座標, 檢查滑鼠或鍵盤的狀態..等.&lt;br /&gt;&lt;br /&gt;在&lt;span style=&quot;font-weight: bold;&quot;&gt;WPF/Silverlight&lt;/span&gt;中, 可以透過下列方式來實作Game Loop,分別是:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-family:arial;&quot;&gt; &lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.threading.dispatchertimer%28VS.95%29.aspx&quot;&gt;DispatcherTimer&lt;/a&gt;    - 可以在指定的時間間隔內, 處理&lt;/span&gt;&lt;span&gt;佇列中的執行緒.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-family:arial;&quot;&gt; &lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.media.animation.storyboard%28VS.95%29.aspx&quot;&gt;Storyboard&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;   - &lt;span style=&quot;font-family:arial;&quot;&gt;以時間軸控制動畫, 和&lt;span style=&quot;font-weight: bold;&quot;&gt;DispatcherTimer&lt;/span&gt;的作法類似, 透過&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;Duration&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;屬性決定時間長短, 然後在&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;Completed&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;事件中再次呼叫&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;Storyboard&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;的&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;Begin&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;方法, 就可以達到類似計時器的迴圈&lt;/span&gt;.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.media.compositiontarget.rendering%28VS.90%29.aspx&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;CompositionTarget.Rendering&lt;/span&gt;&lt;/a&gt;  -  &lt;span style=&quot;font-family:arial;&quot;&gt;每當程式要顯示一個畫面(frame)時, 就會引發Rendering事件&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;下列程式碼將示範如何使用上述的方法&lt;/span&gt;&lt;span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;, 我們會讓一個圓球在視窗內作移動, 當碰到邊界時會作反彈,  而圓球的座標是在Game Loop中作更新, 並顯示對應的FPS值, &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;如下圖所示:&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEir653zXyz480FXzMRTLe_iyO_6i7a1gwc12oV_xeOqq8CU5IGBozE7YJNC6D93h3ZWMWbmKUz8GpNFXwoCewy_aM6A5hMiNmN5YBZJjqaJuQuzdUHtL-f9QGrsff0-4om4YmalSNBU6CA-/s1600/gameloop.png&quot;&gt;&lt;img style=&quot;display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 400px; height: 311px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEir653zXyz480FXzMRTLe_iyO_6i7a1gwc12oV_xeOqq8CU5IGBozE7YJNC6D93h3ZWMWbmKUz8GpNFXwoCewy_aM6A5hMiNmN5YBZJjqaJuQuzdUHtL-f9QGrsff0-4om4YmalSNBU6CA-/s400/gameloop.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5475372974642422338&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;                                                         &lt;span style=&quot;font-family:arial;&quot;&gt;  [圖 1]利用Game Loop作動畫&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;/span&gt;xmal檔如下:&lt;br /&gt;&lt;pre class=&quot;xml&quot; name=&quot;code&quot;&gt;&lt;br /&gt;&amp;lt;Window x:Class=&quot;GameLoopTesting.Window1&quot;&lt;br /&gt;    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;&lt;br /&gt;    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;&lt;br /&gt;    Title=&quot;Window1&quot; SizeToContent=&quot;WidthAndHeight&quot;&amp;gt;&lt;br /&gt;    &amp;lt;Canvas x:Name=&quot;LayoutRoot&quot; Background=&quot;Black&quot; Width=&quot;800&quot; Height=&quot;600&quot;&amp;gt;&lt;br /&gt;        &amp;lt;TextBlock x:Name=&quot;txtFPS&quot; &lt;br /&gt;                   Foreground=&quot;White&quot;&lt;br /&gt;                   FontFamily=&quot;Arial&quot;&lt;br /&gt;                   FontSize=&quot;24&quot;&lt;br /&gt;                   Text=&quot;FPS:&quot; &lt;br /&gt;                   Panel.ZIndex=&quot;99&quot;/&amp;gt;&lt;br /&gt;        &amp;lt;Ellipse x:Name=&quot;ball&quot; &lt;br /&gt;                 Width=&quot;50&quot; &lt;br /&gt;                 Height=&quot;50&quot; &lt;br /&gt;                 Fill=&quot;LightBlue&quot; &lt;br /&gt;                 Stroke=&quot;Gray&quot;&lt;br /&gt;                 Canvas.Left=&quot;100&quot;&lt;br /&gt;                 Canvas.Top=&quot;100&quot;&amp;gt;   &lt;br /&gt;        &amp;lt;/Ellipse&amp;gt;    &lt;br /&gt;    &amp;lt;/Canvas&amp;gt;&lt;br /&gt;&amp;lt;/Window&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;&lt;br /&gt;cs檔如下:&lt;br /&gt;using System;&lt;br /&gt;using System.Windows;&lt;br /&gt;using System.Windows.Controls;&lt;br /&gt;using System.Windows.Media;&lt;br /&gt;using System.Windows.Threading;&lt;br /&gt;using System.Windows.Media.Animation;&lt;br /&gt;&lt;br /&gt;namespace GameLoopTesting&lt;br /&gt;{&lt;br /&gt;    /// &amp;lt;summary&amp;gt;&lt;br /&gt;    /// Interaction logic for Window1.xaml&lt;br /&gt;    /// &amp;lt;/summary&amp;gt;&lt;br /&gt;    public partial class Window1 : Window&lt;br /&gt;    {&lt;br /&gt;        public enum GameLoopType&lt;br /&gt;        {&lt;br /&gt;            DISPATCHERTIMER,&lt;br /&gt;            STORYBOARD,&lt;br /&gt;            RENDERING&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// For object parameters&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        private float radius;&lt;br /&gt;        private double dx = 1;&lt;br /&gt;        private double dy = 1;&lt;br /&gt;        private double x = 0;&lt;br /&gt;        private double y = 0;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// For FPS property&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        private int _frameCounter = 0;&lt;br /&gt;        private double _timeSinceLastUpdate = 0.0;&lt;br /&gt;        private DateTime _lastUpdateTime = DateTime.MinValue;&lt;br /&gt;        private double _fpsValue = 0.0;&lt;br /&gt;&lt;br /&gt;        private Storyboard _sbTrigger;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        public Window1()&lt;br /&gt;        {&lt;br /&gt;            InitializeComponent();&lt;br /&gt;&lt;br /&gt;            radius = (float)ball.Width/2;&lt;br /&gt;            _lastUpdateTime = DateTime.Now;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;            ///Switch game loop type&lt;br /&gt;            SwitchGameLoop(GameLoopType.DISPATCHERTIMER);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        void SwitchGameLoop(GameLoopType gameLoopType)&lt;br /&gt;        {&lt;br /&gt;            switch (gameLoopType)&lt;br /&gt;            {&lt;br /&gt;                case GameLoopType.DISPATCHERTIMER:&lt;br /&gt;                    {&lt;br /&gt;                        DispatcherTimer timer = new DispatcherTimer();&lt;br /&gt;                        timer.Interval = TimeSpan.FromMilliseconds(10);&lt;br /&gt;                        timer.Tick += new EventHandler(timer_Tick);&lt;br /&gt;                        timer.Start();&lt;br /&gt;                    }&lt;br /&gt;                    break;&lt;br /&gt;&lt;br /&gt;                case GameLoopType.STORYBOARD:&lt;br /&gt;                    {                     &lt;br /&gt;                        _sbTrigger = new Storyboard();     &lt;br /&gt;                        _sbTrigger.Duration = TimeSpan.FromMilliseconds(10);&lt;br /&gt;                        _sbTrigger.Completed += new EventHandler(sbTrigger_Completed);&lt;br /&gt;                        _sbTrigger.Begin();&lt;br /&gt;&lt;br /&gt;                    }&lt;br /&gt;                    break;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;                case GameLoopType.RENDERING:&lt;br /&gt;                    {&lt;br /&gt;                        CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);&lt;br /&gt;&lt;br /&gt;                    }&lt;br /&gt;                    break;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        void timer_Tick(object sender, EventArgs e)&lt;br /&gt;        {&lt;br /&gt;            /// Calculate FPS value&lt;br /&gt;            /// -----------------------------------------------------------&lt;br /&gt;            _frameCounter++;&lt;br /&gt;&lt;br /&gt;            if ((DateTime.Now - _lastUpdateTime).Seconds &gt;= 1)&lt;br /&gt;            {&lt;br /&gt;                txtFPS.Text = &quot;FPS : &quot; + _frameCounter;&lt;br /&gt;                _frameCounter = 0;&lt;br /&gt;                _lastUpdateTime = DateTime.Now;&lt;br /&gt;            }&lt;br /&gt;            //-----------------------------------------------------------&lt;br /&gt;&lt;br /&gt;            UpdateObjectPosition();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        void sbTrigger_Completed(object sender, EventArgs e)&lt;br /&gt;        {&lt;br /&gt;            UpdateObjectPosition();&lt;br /&gt;            _sbTrigger.Begin();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        void CompositionTarget_Rendering(object sender, EventArgs e)&lt;br /&gt;        {&lt;br /&gt;            /// Calculate FPS value&lt;br /&gt;            /// -----------------------------------------------------------&lt;br /&gt;            TimeSpan elapsedTime = DateTime.Now - _lastUpdateTime;&lt;br /&gt;&lt;br /&gt;            _frameCounter++;&lt;br /&gt;            _timeSinceLastUpdate += elapsedTime.TotalSeconds;&lt;br /&gt;&lt;br /&gt;            if (_frameCounter &gt;= 100)&lt;br /&gt;            {&lt;br /&gt;                _fpsValue = (int)(_frameCounter / _timeSinceLastUpdate);&lt;br /&gt;                txtFPS.Text = &quot;FPS : &quot; + _fpsValue;&lt;br /&gt;&lt;br /&gt;                _frameCounter = 0;&lt;br /&gt;                _timeSinceLastUpdate = 0;&lt;br /&gt;            }&lt;br /&gt;            _lastUpdateTime = DateTime.Now;&lt;br /&gt;            //----------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;            UpdateObjectPosition();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        /// &amp;lt;summary&amp;gt;&lt;br /&gt;        /// Update the position of object&lt;br /&gt;        /// &amp;lt;/summary&amp;gt;&lt;br /&gt;        private void UpdateObjectPosition()&lt;br /&gt;        {&lt;br /&gt;            x = ((double)Canvas.GetLeft(ball));&lt;br /&gt;            y = ((double)Canvas.GetTop(ball));&lt;br /&gt;&lt;br /&gt;            x += dx;&lt;br /&gt;            y += dy;&lt;br /&gt;&lt;br /&gt;            Canvas.SetLeft(ball, x);&lt;br /&gt;            Canvas.SetTop(ball, y);&lt;br /&gt;&lt;br /&gt;            if (x &gt; LayoutRoot.Width - 2 * radius)&lt;br /&gt;            {&lt;br /&gt;                dx = -Math.Abs(dx);&lt;br /&gt;            }&lt;br /&gt;            if (x &lt; 0)&lt;br /&gt;            {&lt;br /&gt;                dx = Math.Abs(dx);&lt;br /&gt;            }&lt;br /&gt;            if (y &gt; LayoutRoot.Height - 2 * radius)&lt;br /&gt;            {&lt;br /&gt;                dy = -Math.Abs(dy);&lt;br /&gt;            }&lt;br /&gt;            if (y &lt; 0)&lt;br /&gt;            {&lt;br /&gt;                dy = Math.Abs(dy);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;總 結:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;    * 在&lt;span style=&quot;font-weight: bold;&quot;&gt;WPF&lt;/span&gt;中使用&lt;span style=&quot;font-weight: bold;&quot;&gt;Storyboard&lt;/span&gt;作Game Loop時, 會發生畫面更新到一半時, 卻停止更新,但&lt;span style=&quot;font-weight: bold;&quot;&gt;Silverlight&lt;/span&gt;上卻不會, 原因目前還不知道.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;    * 透過上述的3種方式, 都可以作為遊戲的迴圈, 不過穩定度和解析度上有所差別.可參考這篇&lt;a href=&quot;http://www.dotblogs.com.tw/kan/archive/2009/11/09/11502.aspx&quot;&gt;Game Loop&lt;/a&gt;部落格的詳細比較.&lt;/span&gt;&lt;br /&gt;就穩定度來說 :&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span style=&quot;color: rgb(255, 153, 255);&quot;&gt;  &lt;span style=&quot;color: rgb(51, 51, 255);&quot;&gt;CompositionTarget.Rendering &gt; Storyboard &gt; DispatcherTimer&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;參考文章:&lt;/span&gt;&lt;br /&gt;&lt;a href=&quot;http://www.bluerosegames.com/silverlight-games-101/post/Creating-a-Game-Loop.aspx&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;Creating a Game Loop&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;a href=&quot;http://windowsclient.net/downloads/folders/controlgallery/entry2391.aspx&quot;&gt;Application (Game) Loop, FPS and Sprite like Animation&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;a href=&quot;http://www.dotblogs.com.tw/kan/archive/2009/11/09/11502.aspx&quot;&gt;Game  Loop&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/4381655300442225312/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2010/04/game-loop-dispactertimer-storyboard.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/4381655300442225312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/4381655300442225312'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2010/04/game-loop-dispactertimer-storyboard.html' title='Game Loop  Compare- DispacterTimer, Storyboard, Composition.Rendering'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEir653zXyz480FXzMRTLe_iyO_6i7a1gwc12oV_xeOqq8CU5IGBozE7YJNC6D93h3ZWMWbmKUz8GpNFXwoCewy_aM6A5hMiNmN5YBZJjqaJuQuzdUHtL-f9QGrsff0-4om4YmalSNBU6CA-/s72-c/gameloop.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-805830409304142275</id><published>2010-04-13T04:35:00.001-07:00</published><updated>2010-04-13T18:06:04.168-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Silverlight"/><title type='text'>如何在Silverlight的應用程式上作Debug</title><content type='html'>&lt;span style=&quot;font-family:arial;&quot;&gt;在開發Silverlight的應用程式時, 你可能要用到Debug功能, 來找出程式的錯誤, 但在Silverlight專案執行&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;Debug功能, 可能會出現下面訊息, 而無法除錯.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; &lt;a style=&quot;font-family: arial;&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0eZlOdD3aleCelkmbyuii1kj2BnUEZY5CihmbQFAlCUSGxIn2eqtbuJK4nNRkuLNXx5embBmgGxz7vT9OaZHJ9deIvcve1SoPVQhThXTJgcJswWXIhxDES7ed4-BMcUSrveaVnlz9tuBz/s1600/DEBUG.png&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 400px; height: 96px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0eZlOdD3aleCelkmbyuii1kj2BnUEZY5CihmbQFAlCUSGxIn2eqtbuJK4nNRkuLNXx5embBmgGxz7vT9OaZHJ9deIvcve1SoPVQhThXTJgcJswWXIhxDES7ed4-BMcUSrveaVnlz9tuBz/s400/DEBUG.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5459587525244018514&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;    &lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;br /&gt;解決的方法如下 :&lt;/span&gt; &lt;ul style=&quot;font-family: arial;&quot;&gt;&lt;li&gt;安裝&lt;a href=&quot;http://www.microsoft.com/downloads/details.aspx?familyid=9442B0F2-7465-417A-88F3-5E7B5409E9DD&amp;amp;displaylang=en&quot;&gt; Microsoft® Silverlight™ 3 Tools for Visual Studio 2008 SP1 工具&lt;/a&gt;&lt;/li&gt;&lt;li&gt;安裝&lt;a href=&quot;http://go.microsoft.com/fwlink/?LinkID=150228&quot;&gt;Silverlight_Developer.exe&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;           Visual Studio 2008 SP1 的 Silverlight 3 Tools 包括：&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;               * Visual Basic 和 C# 專案範本&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;               * Intellisense 和 XAML 程式碼產生器&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;               * Silverlight 應用程式偵錯&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;               * 適用於 Mac 的 Silverlight 應用程式遠端偵錯&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;               * Web 參考支援&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;               * WCF 範本&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;               * Team Build 和命令列建置支援&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;               * 支援快取的透明平台擴充程式&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;               * 支援 Silverlight 3 瀏覽器外用應用程式 &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;安裝上述工具後, 即可解決上述問題.&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;另外若預設瀏覽器可能不是IE, 可能會發生執行Silverlight的程式沒有畫面, 此時就必須將IE設定為預設瀏覽器, 作法如下:&lt;/span&gt;&lt;br /&gt;&lt;ol style=&quot;font-family: arial;&quot;&gt;&lt;li&gt;開啟 Internet Explorer 瀏覽器視窗。&lt;/li&gt;&lt;li&gt;選取 [工具] &gt; [網際網路選項]。&lt;/li&gt;&lt;li&gt;選取 [程式集] 標籤。&lt;/li&gt;&lt;li&gt;在 [預設網頁瀏覽器] 區段中按一下 [設成預設值]。&lt;/li&gt;&lt;li&gt;按一下 [確定]&lt;/li&gt;&lt;/ol&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/805830409304142275/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2010/04/silverlightdebug.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/805830409304142275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/805830409304142275'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2010/04/silverlightdebug.html' title='如何在Silverlight的應用程式上作Debug'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0eZlOdD3aleCelkmbyuii1kj2BnUEZY5CihmbQFAlCUSGxIn2eqtbuJK4nNRkuLNXx5embBmgGxz7vT9OaZHJ9deIvcve1SoPVQhThXTJgcJswWXIhxDES7ed4-BMcUSrveaVnlz9tuBz/s72-c/DEBUG.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-1668551958400721545</id><published>2010-04-11T23:13:00.000-07:00</published><updated>2010-11-26T00:56:28.982-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Farseer"/><category scheme="http://www.blogger.com/atom/ns#" term="Game"/><category scheme="http://www.blogger.com/atom/ns#" term="Multi-touch"/><category scheme="http://www.blogger.com/atom/ns#" term="Silverlight"/><title type='text'>Touch Game Framework</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;最近要開發一些&lt;b&gt;Touch&lt;/b&gt;的遊戲, 所以構思了整個&lt;b&gt;Game Framework&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;下面的表格列出之前survey的一些&lt;b&gt;game engine,&lt;/b&gt;  不過對我來說還是有一些技術性的問題,例如: &lt;b&gt;touch&lt;/b&gt;功能的支援, &lt;b&gt;UI&lt;/b&gt;的建立, &lt;/span&gt;軟體收費, 支援平台等等.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgO-Qm2x4_4vOe6ohWK0Q4dFdx2SCuFTnd1dvwOczt_uNB8b5qDHLL6KSY9ILpoxWvvDPK90IavAv6K_S8zOKMq4IDyq3QWLLqpEo0O9pFa2oz-3mur91ksJzIS6gzjvu8c7-m9ct5G0MWS/s1600/GAME+ENGINE.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5459820309111257282&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgO-Qm2x4_4vOe6ohWK0Q4dFdx2SCuFTnd1dvwOczt_uNB8b5qDHLL6KSY9ILpoxWvvDPK90IavAv6K_S8zOKMq4IDyq3QWLLqpEo0O9pFa2oz-3mur91ksJzIS6gzjvu8c7-m9ct5G0MWS/s1600/GAME+ENGINE.png&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;[圖] &lt;b&gt;XNA&lt;/b&gt;, &lt;b&gt;Unity&lt;/b&gt;, &lt;b&gt;Blender&lt;/b&gt;的比較表&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
所以最後構思的遊戲架構如下:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;應用程式&lt;/span&gt; - 選用&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/bb404700%28VS.95%29.aspx&quot;&gt;Silverlight&lt;/a&gt;平台, 主要優點如下:&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;    豐富的圖形及使用者互動功能: &lt;b&gt;Silverlight &lt;/b&gt;包含了 &lt;b&gt;WPF&lt;/b&gt;技術的子集,可大幅擴充瀏覽器中用來建立 &lt;b&gt;UI &lt;/b&gt;的項目. 另外, 它具有向量式的繪圖能力, 3D繪圖和製作動畫等等.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;    影音播放 - 它會以資料流方式處理視訊和音訊. 它可以調整視訊品質, 以配合從行動裝置到桌面瀏覽器, 甚至是到 720p HDTV 視訊模式等任何裝置.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;    支援&lt;b&gt;Windows 7&lt;/b&gt; 的&lt;b&gt;Touch&lt;/b&gt;功能 - &lt;b&gt;Silverlight &lt;/b&gt;在3.0版本後就支援&lt;b&gt;Windows 7&lt;/b&gt;的觸控功能, 可參考這篇文章的簡介 - &lt;a href=&quot;http://johnniebooks.blogspot.com/2010/02/silverlight-30-multi-touch.html?utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed%3A+ThinkingAndCoding+%28Thinking+and+Coding%29&quot;&gt;Silverlight 3.0 + Multi-touch&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;    跨瀏覽器、跨平台的支援 - 它可以在所有常見的 &lt;b&gt;Web &lt;/b&gt;瀏覽器 (包括 &lt;b&gt;Microsoft Internet Explorer&lt;/b&gt;、&lt;b&gt;Mozilla Firefox &lt;/b&gt;和 &lt;b&gt;Apple Safari&lt;/b&gt;) 以及 Microsoft Windows 和&lt;b&gt; Apple Mac OS &lt;/b&gt;上執行&lt;b&gt;Silverlight&lt;/b&gt;, 可參考 =&amp;gt;&lt;a href=&quot;http://www.microsoft.com/getsilverlight/get-started/install/default.aspx#sysreq&quot;&gt;支援的平台和瀏覽器&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;物理引擎&lt;/span&gt; - 選用&lt;a href=&quot;http://en.wikipedia.org/wiki/Farseer_Physics_Engine&quot;&gt;Farseer Physics Engine&lt;/a&gt;. 它是一個在&lt;b&gt;.NET&lt;/b&gt;平台上使用的物理引擎(它是open source), 主要用來開發Silverlight和&lt;a href=&quot;http://zh.wikipedia.org/zh-tw/XNA_Game_Studio_Express&quot;&gt;XNA&lt;/a&gt;的&lt;b&gt;2D&lt;/b&gt;遊戲. 它提供很多物理相關的特性, 例如: 重力, 作用力, 力矩,碰撞,彈簧和關節..等等&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;參考文章 :&lt;br /&gt;
&lt;a href=&quot;http://farseerphysics.codeplex.com/Wikipage&quot;&gt;Farseer Physics Engine 3.0&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;                   &lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/cc838158%28VS.95%29.aspx&quot;&gt; msdn - Silverlight&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/1668551958400721545/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2010/04/touch-game-framework.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/1668551958400721545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/1668551958400721545'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2010/04/touch-game-framework.html' title='Touch Game Framework'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgO-Qm2x4_4vOe6ohWK0Q4dFdx2SCuFTnd1dvwOczt_uNB8b5qDHLL6KSY9ILpoxWvvDPK90IavAv6K_S8zOKMq4IDyq3QWLLqpEo0O9pFa2oz-3mur91ksJzIS6gzjvu8c7-m9ct5G0MWS/s72-c/GAME+ENGINE.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-841498623252069554</id><published>2010-02-24T02:42:00.000-08:00</published><updated>2010-11-26T00:58:25.608-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Multi-touch"/><category scheme="http://www.blogger.com/atom/ns#" term="Silverlight"/><title type='text'>Silverlight 3.0 + Multi-touch</title><content type='html'>&lt;a href=&quot;http://zh.wikipedia.org/wiki/Microsoft_Silverlight&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;Silverlight&lt;/span&gt;&lt;/a&gt;是微軟最新的&lt;i style=&quot;font-family: arial;&quot;&gt;&lt;/i&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;Web&lt;/span&gt;用戶介面&lt;i&gt;&lt;/i&gt;技術，它能夠跨流覽器、跨平臺運行.&lt;br /&gt;
而&lt;span style=&quot;font-family: arial;&quot;&gt;在&lt;a href=&quot;http://www.silverlight.net/getstarted/silverlight3/&quot;&gt;Silverlight 3.0&lt;/a&gt;&lt;/span&gt; 上也支援多點觸控功能 , 但目前功能還是相當有限, 只能取得觸控點的資料,&lt;br /&gt;
若要想要有手勢的功能的話, 需要透過觸控點另外作計算.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: arial; font-weight: bold;&quot;&gt;Silverlight&lt;/span&gt;的多點觸控架構如下:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKVitqYi71YCWL4alYPs4R1xisZ0t2unJMf3uItNiffO5U1V_Q8GuQ_tpdkFntZf-KyJXTt7SKbLHubzQu53hYznlK7icggUk1ksM99qx3LAWbAbmZZNEgUrSEbVz-UAJSkYb0TV4y37ZI/s1600/s3touch.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;480&quot; id=&quot;BLOGGER_PHOTO_ID_5454969381183534978&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKVitqYi71YCWL4alYPs4R1xisZ0t2unJMf3uItNiffO5U1V_Q8GuQ_tpdkFntZf-KyJXTt7SKbLHubzQu53hYznlK7icggUk1ksM99qx3LAWbAbmZZNEgUrSEbVz-UAJSkYb0TV4y37ZI/s640/s3touch.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
從上圖可知, 要寫一個&lt;span style=&quot;font-family: arial; font-weight: bold;&quot;&gt;Silverlight&lt;/span&gt;的觸控程式, 必要元素要有: &lt;span style=&quot;font-family: arial; font-weight: bold;&quot;&gt;Touch Device +&lt;/span&gt;&lt;span style=&quot;font-family: arial; font-weight: bold;&quot;&gt; Windows 7 + IE 8&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
和&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Windows Touch API&lt;/span&gt; 不一樣的地方&lt;/span&gt;, &lt;span style=&quot;font-family: arial; font-weight: bold;&quot;&gt;Silverlight&lt;/span&gt; &lt;span style=&quot;font-family: arial;&quot;&gt;不需要註冊&lt;span class=&quot;code&quot; style=&quot;font-weight: bold;&quot;&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd317326%28VS.85%29.aspx&quot;&gt;RegisterTouchWindow&lt;/a&gt;, &lt;/span&gt;&lt;span class=&quot;code&quot;&gt;它&lt;/span&gt;&lt;/span&gt;是以整個應用程式為範圍來註冊多點觸控事件, 而不是在&lt;span style=&quot;font-family: arial; font-weight: bold;&quot;&gt;UIElement &lt;/span&gt;加入觸控事件&lt;span style=&quot;font-family: arial;&quot;&gt;(WPF)&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
撰寫&lt;span style=&quot;font-family: arial;&quot;&gt;Silverlight multi-touch application&lt;/span&gt;的流程如下:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;(1)&lt;/span&gt;註冊多點觸控的處理常式 - &lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.input.touch.framereported%28VS.95%29.aspx&quot;&gt;&lt;span style=&quot;font-family: arial; font-weight: bold;&quot;&gt;TouchFrameReported&lt;/span&gt;&lt;/a&gt;(它是一個&lt;span style=&quot;font-family: arial;&quot;&gt;static function&lt;/span&gt;)&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;Touch.FrameReported += &lt;span style=&quot;color: #000099;&quot;&gt;new&lt;/span&gt; TouchFrameEventHandler(Touch_FrameReported);&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
針對多點觸控所發生的事件，&lt;span style=&quot;font-family: arial; font-weight: bold;&quot;&gt;Silverlight&lt;/span&gt;預設將多點觸控事件提升為滑鼠事件, 若不希望升級成滑鼠事件, 可以呼叫 &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.input.touchframeeventargs.suspendmousepromotionuntiltouchup%28VS.96%29.aspx&quot;&gt;&lt;span style=&quot;font-family: arial; font-weight: bold;&quot;&gt;SuspendMousePromotionUntilTouchUp&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;(2)&lt;/span&gt;取得觸控點的資料                                                                                                                              &lt;span style=&quot;font-size: 100%;&quot;&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.input.touchframeeventargs.getprimarytouchpoint%28VS.95%29.aspx&quot;&gt;TouchPoint GetPrimaryTouchPoint(UIElement relativeTo)&lt;/a&gt;  --&amp;gt;  取得主要觸控點資料&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;span style=&quot;font-family: arial; font-size: 100%;&quot;&gt;     &lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.input.touchframeeventargs.gettouchpoints%28VS.95%29.aspx&quot;&gt;TouchPointCollection  GetTouchPoints(UIElement relativeTo)&lt;/a&gt;   --&amp;gt; 取得所有觸控點資料&lt;/span&gt;        &lt;/div&gt;&lt;span style=&quot;font-family: arial; font-weight: bold;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
傳入一個&lt;span style=&quot;font-family: arial; font-weight: bold;&quot;&gt;UIElement&lt;/span&gt;將回傳相對偏移的&lt;span style=&quot;font-family: arial;&quot;&gt; &lt;span style=&quot;font-family: arial; font-weight: bold;&quot;&gt;Position&lt;/span&gt; &lt;/span&gt;產生包含相對座標的&lt;span style=&quot;font-weight: bold;&quot;&gt; &lt;span style=&quot;font-family: arial;&quot;&gt;TouchPoint&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;
如果想要獲得觸控點的的絕對座標, 請將&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt; &lt;span style=&quot;font-family: arial;&quot;&gt;relativeTo&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;指定為 &lt;span style=&quot;font-family: arial; font-weight: bold;&quot;&gt;null&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
觸控點的其他資訊如下所示;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;example code:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;color: #3333ff;&quot;&gt;foreach&lt;/span&gt; (TouchPoint tp in e.GetTouchPoints(_canvas))&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;{&lt;/span&gt; &lt;span style=&quot;font-family: arial;&quot;&gt;   &lt;span style=&quot;color: #006600;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;color: #006600;&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;        // 取得作業系統針對特定觸控裝置所提供的唯一 ID&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;font-family: arial;&quot;&gt;   &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;        tp.TouchDevice.Id;&lt;/span&gt;  &lt;span style=&quot;font-family: arial;&quot;&gt;   &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;        // 取得當觸控點產生時，滑鼠指標所停留的最上層 UIElement 物件&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;font-family: arial;&quot;&gt;  &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;     tp.TouchDevice.DirectlyOver&lt;/span&gt;  &lt;span style=&quot;font-family: arial;&quot;&gt;   &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;         // 取得觸控點的 X, Y 座標位置(相當於觸控區域的中心點位置)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;tp.Position;&lt;/span&gt;  &lt;span style=&quot;font-family: arial;&quot;&gt;   &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;    // 取得觸控點接觸區域(其區域為一個矩形)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;    tp.Size;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;(3) 識別觸控的動作 -&lt;/span&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.input.touchaction%28VS.95%29.aspx&quot;&gt;&lt;span style=&quot;font-family: arial; font-weight: bold;&quot;&gt;TouchAction&lt;/span&gt;&lt;/a&gt; &lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
觸控點的動作可分成下列3種:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;      TouchAction.Down: 來自 &lt;span class=&quot;input&quot;&gt;TOUCHEVENTF_DOWN&lt;/span&gt;  訊息的觸控動作&lt;/span&gt; &lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
TouchAction.Move: 來自 &lt;span class=&quot;input&quot;&gt;TOUCHEVENTF_MOVE&lt;/span&gt;  訊息的觸控動作&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;  TouchAction.Up:來自 &lt;span class=&quot;input&quot;&gt;TOUCHEVENTF_UP&lt;/span&gt;  訊息的觸控動作&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
下圖為利用&lt;span style=&quot;font-weight: bold;&quot;&gt;Silverlight&lt;/span&gt;開發的繪圖板. 因此在網頁上也可利用觸控作繪圖.&lt;br /&gt;
&lt;/span&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDgcYm2acey46xp9wWEs4XoA39mmyKwS85w5k93ccrTLqE4MFrN53axrpwf4PK-RW199dKoZOTyxWI5T4ICXtc7byDHoFZ6HoOw2IdT6ZOTzIjminCqp8vmlDMfPUm6ZIg2lVpKzSV28ZB/s1600/s3+ink.bmp&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;344&quot; id=&quot;BLOGGER_PHOTO_ID_5455005187458834610&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDgcYm2acey46xp9wWEs4XoA39mmyKwS85w5k93ccrTLqE4MFrN53axrpwf4PK-RW199dKoZOTyxWI5T4ICXtc7byDHoFZ6HoOw2IdT6ZOTzIjminCqp8vmlDMfPUm6ZIg2lVpKzSV28ZB/s640/s3+ink.bmp&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;P.S: 若要使用&lt;span style=&quot;font-weight: bold;&quot;&gt;Silverlight&lt;/span&gt; 來作為開發工具. 如果您沒有 &lt;span style=&quot;font-weight: bold;&quot;&gt;Visual Web Developer&lt;/span&gt;,請使用      &lt;/span&gt;&lt;a href=&quot;http://www.microsoft.com/web/gallery/install.aspx?appsxml=&amp;amp;appid=VWD;Silverlight3Tools;SilverlightToolkit;RIAServices&quot; style=&quot;font-family: arial;&quot;&gt;      Web Platform Installer&lt;/a&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;,如果您已有&lt;span style=&quot;font-weight: bold;&quot;&gt; Visual Studio&lt;/span&gt;,      &lt;/span&gt;&lt;a href=&quot;http://go.microsoft.com/fwlink/?LinkID=143571&quot; style=&quot;font-family: arial;&quot;&gt;請直接下載這個工具&lt;/a&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;  (      &lt;/span&gt;&lt;a href=&quot;http://go.microsoft.com/fwlink/?LinkID=157102&quot; style=&quot;font-family: arial;&quot;&gt;Silverlight        3 SDK&lt;/a&gt;&lt;span style=&quot;font-family: arial;&quot;&gt; )&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
參考文章:&lt;br /&gt;
&lt;a href=&quot;http://timheuer.com/blog/archive/2009/07/30/silverlight-3-multi-touch-introduction-fundamentals-basics.aspx&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;Silverlight 3 Multi-touch: The Basics&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://studyhost.blogspot.com/2009/10/silverlight-3-multi-touch.html&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;Silverlight 3 中的multi-Touch程式開發&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;text-decoration: underline;&quot;&gt;&lt;br /&gt;
&lt;a href=&quot;http://jobijoy.blogspot.com/2009/08/silverlight-3-multi-touch-with-windows.html&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;Silverlight 3 Multi-Touch with Windows 7 and HP Touch Smart&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/841498623252069554/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2010/02/silverlight-30-multi-touch.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/841498623252069554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/841498623252069554'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2010/02/silverlight-30-multi-touch.html' title='Silverlight 3.0 + Multi-touch'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKVitqYi71YCWL4alYPs4R1xisZ0t2unJMf3uItNiffO5U1V_Q8GuQ_tpdkFntZf-KyJXTt7SKbLHubzQu53hYznlK7icggUk1ksM99qx3LAWbAbmZZNEgUrSEbVz-UAJSkYb0TV4y37ZI/s72-c/s3touch.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-6338785100408367745</id><published>2009-11-18T21:40:00.000-08:00</published><updated>2009-11-30T21:08:54.977-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Multi-touch"/><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><title type='text'>WPF + Windows7 Multi-touch (Part 3)</title><content type='html'>&lt;div  style=&quot;text-align: justify;font-family:arial;&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;目前在&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;WPF&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;中使用&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;Multi-touch&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;功能,必須透過&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;P/Invoke&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;的方式呼叫&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;Win32 Touch API&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;的功能(可參考這篇文章 : &lt;/span&gt;&lt;a style=&quot;font-family: arial;&quot; href=&quot;http://johnniebooks.blogspot.com/2009/10/wpf-windows7-multi-touch-part-2.html&quot;&gt;WPF + Windows7 Multi-touch (Part 2) &lt;/a&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;)&lt;/span&gt;, 或是可以直接使用微軟提供的&lt;a href=&quot;http://code.msdn.microsoft.com/WindowsTouch/Release/ProjectReleases.aspx?ReleaseId=2127&quot;&gt;Windows 7 Multitouch .NET Interop Sample Library&lt;/a&gt;, 它提供 &lt;span style=&quot;font-weight: bold;&quot;&gt;WPF &lt;/span&gt;與 &lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;WinForms 3.5 SP1&lt;/span&gt; &lt;/span&gt;要開發&lt;span style=&quot;font-weight: bold;&quot;&gt;Multi-Touch&lt;/span&gt; 程式所需的功能, 不過利用上述這些方法開發觸控功能時, 還是有稍嫌複雜, 也不是很直覺.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;因此在&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;WPF 4.0&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt; 已經將一些觸控功能放到&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;UIElement&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;UIElement3D&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;和&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;ContentElement&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;中,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;在&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt; Beta 1&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;中, 將支援高階操作的觸控功能(Manipulation), 如下所示:&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;ul style=&quot;text-align: justify; font-family: arial;&quot;&gt;&lt;li&gt;   &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.uielement.manipulationstarted%28VS.100%29.aspx&quot;&gt;ManipulationStarted&lt;/a&gt;&lt;/li&gt;&lt;li&gt;   &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.uielement.manipulationdelta%28VS.100%29.aspx&quot;&gt;ManipulationDelta&lt;/a&gt;&lt;/li&gt;&lt;li&gt;   &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.uielement.manipulationinertiastarting%28VS.100%29.aspx&quot;&gt;ManipulationInertiaStarting&lt;/a&gt;&lt;/li&gt;&lt;li&gt;   &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.uielement.manipulationcompleted%28VS.100%29.aspx&quot;&gt;ManipulationCompleted&lt;/a&gt; &lt;/li&gt;&lt;li&gt;   &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.uielement.manipulationboundaryfeedback%28VS.100%29.aspx&quot;&gt;ManipulationBoundaryFeedback&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div  style=&quot;text-align: justify;font-family:arial;&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;而在&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;Beta 2&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt; 中,&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt; &lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;除了原本高階操作的觸控功能(Manipulation)外, 還提供的&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;Touch&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;相關的event,如下所示:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;      &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.uielement.previewtouchdown%28VS.100%29.aspx&quot;&gt;PreviewTouchDown&lt;/a&gt;&lt;/li&gt;&lt;li&gt;      &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.uielement.touchdown%28VS.100%29.aspx&quot;&gt;TouchDown&lt;/a&gt;&lt;/li&gt;&lt;li&gt;      &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.uielement.previewtouchmove%28VS.100%29.aspx&quot;&gt;PreviewTouchMove&lt;/a&gt;&lt;/li&gt;&lt;li&gt;      &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.uielement.touchmove%28VS.100%29.aspx&quot;&gt;TouchMove&lt;/a&gt;&lt;/li&gt;&lt;li&gt;      &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.uielement.previewtouchup%28VS.100%29.aspx&quot;&gt;PreviewTouchUp&lt;/a&gt;&lt;/li&gt;&lt;li&gt;      &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.uielement.touchmove%28VS.100%29.aspx&quot;&gt;TouchUp&lt;/a&gt;&lt;/li&gt;&lt;li&gt;      &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.uielement.gottouchcapture%28VS.100%29.aspx&quot;&gt;GotTouchCapture&lt;/a&gt;&lt;/li&gt;&lt;li&gt;      &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.uielement.losttouchcapture%28VS.100%29.aspx&quot;&gt;LostTouchCapture&lt;/a&gt;&lt;/li&gt;&lt;li&gt;      &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.uielement.touchenter%28VS.100%29.aspx&quot;&gt;TouchEnter&lt;/a&gt;&lt;/li&gt;&lt;li&gt;      &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.uielement.touchleave%28VS.100%29.aspx&quot;&gt;TouchLeave&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;下面我們將利用&lt;span style=&quot;font-weight: bold;&quot;&gt;WPF 4.0 Beta2&lt;/span&gt; &lt;span style=&quot;font-weight: bold;&quot;&gt;Touch&lt;/span&gt;功能, 撰寫一個顯示目前觸控點的應用程式, 其步驟如下:&lt;br /&gt;&lt;br /&gt;軟體和硬體需求&lt;br /&gt;&lt;ul&gt;&lt;li&gt;IDE -安裝&lt;a href=&quot;http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx&quot;&gt;Visual Studio 2010 Beta 2  &lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;OS 版本 -&lt;a href=&quot;http://www.microsoft.com/windows/windows-7/&quot;&gt; Windows 7 Ultimate Editions&lt;/a&gt;&lt;/li&gt;&lt;li&gt;硬體設備 - 準備一台具有多點觸控的螢幕或電腦&lt;/li&gt;&lt;/ul&gt;程式碼如下:&lt;br /&gt;&lt;br /&gt;XAML檔的部份:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;xml&quot; name=&quot;code&quot;&gt;&lt;br /&gt;&amp;lt;Window x:Class=&quot;WPFTouchPoint.MainWindow&quot;&lt;br /&gt;    xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;&lt;br /&gt;    xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;&lt;br /&gt;    Title=&quot;MainWindow&quot; Height=&quot;800&quot; Width=&quot;800&quot;&lt;br /&gt;    TouchDown=&quot;Window_TouchDown&quot;&lt;br /&gt;    TouchMove=&quot;Window_TouchMove&quot;&lt;br /&gt;    TouchUp=&quot;Window_TouchUp&quot;&amp;gt;&lt;br /&gt;&amp;lt;Canvas Background=&quot;Black&quot;&amp;gt;&lt;br /&gt;    &amp;lt;Ellipse&lt;br /&gt;        Canvas.Left=&quot;0&quot;&lt;br /&gt;        Canvas.Top=&quot;0&quot;&lt;br /&gt;        Name=&quot;Touch1&quot;&lt;br /&gt;        Stroke=&quot;Black&quot;&lt;br /&gt;        Height=&quot;60&quot;&lt;br /&gt;        Width=&quot;60&quot;&lt;br /&gt;        Fill=&quot;LightGreen&quot;&lt;br /&gt;        Visibility=&quot;Hidden&quot;&amp;gt;&lt;br /&gt;        &amp;lt;Ellipse.BitmapEffect&amp;gt;&lt;br /&gt;            &amp;lt;DropShadowBitmapEffect ShadowDepth=&quot;10&quot;&lt;br /&gt;                                    Direction=&quot;270&quot;&lt;br /&gt;                                    Color=&quot;White&quot;&lt;br /&gt;                                    Opacity=&quot;0.5&quot;&lt;br /&gt;                                    Softness=&quot;0.25&quot;/&amp;gt;&lt;br /&gt;        &amp;lt;/Ellipse.BitmapEffect&amp;gt;&lt;br /&gt;    &amp;lt;/Ellipse&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;Ellipse&lt;br /&gt;        Canvas.Left=&quot;0&quot;&lt;br /&gt;        Canvas.Top=&quot;0&quot;&lt;br /&gt;        Name=&quot;Touch2&quot;&lt;br /&gt;        Stroke=&quot;Black&quot;&lt;br /&gt;        Height=&quot;60&quot;&lt;br /&gt;        Width=&quot;60&quot;&lt;br /&gt;        Fill=&quot;LightBlue&quot;&lt;br /&gt;        Visibility=&quot;Hidden&quot;&amp;gt;&lt;br /&gt;        &amp;lt;Ellipse.BitmapEffect&amp;gt;&lt;br /&gt;            &amp;lt;dropshadowbitmapeffect shadowdepth=&quot;10&quot; direction=&quot;270&quot; color=&quot;White&quot;&lt;br /&gt;            opacity=&quot;0.5&quot; softness=&quot;0.25&quot;&amp;gt;&lt;br /&gt;       &amp;lt;/dropshadowbitmapeffect&amp;gt;&lt;br /&gt;     &amp;lt;/Ellipse&amp;gt;&lt;br /&gt;  &amp;lt;/Canvas&amp;gt;&lt;br /&gt; &amp;lt;/Window&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;C#檔的部分:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;&lt;br /&gt;namespace WPFTouchPoint&lt;br /&gt;{&lt;br /&gt;/// &lt;summary&gt;&lt;br /&gt;/// Interaction logic for MainWindow.xaml&lt;br /&gt;/// &lt;/summary&gt;&lt;br /&gt;public partial class MainWindow : Window&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;    private int Touch1ID = 0;    // id for first touch contact&lt;br /&gt;    private int Touch2ID = 0;    // id for second touch contact&lt;br /&gt;&lt;br /&gt;    public MainWindow()&lt;br /&gt;    {&lt;br /&gt;        InitializeComponent();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    private void Window_TouchDown(object sender, TouchEventArgs e)&lt;br /&gt;    {&lt;br /&gt;        TouchPoint p = e.GetTouchPoint(this);&lt;br /&gt;&lt;br /&gt;        if (Touch1ID == 0)&lt;br /&gt;        {&lt;br /&gt;           // Show the touch point&lt;br /&gt;           Touch1.Visibility = Visibility.Visible;&lt;br /&gt;&lt;br /&gt;           Touch1ID = e.TouchDevice.Id;&lt;br /&gt;&lt;br /&gt;           // move the ellipse to the given location&lt;br /&gt;           Touch1.SetValue(Canvas.LeftProperty, p.Position.X - Touch1.Width / 2);&lt;br /&gt;           Touch1.SetValue(Canvas.TopProperty, p.Position.Y - Touch1.Height / 2);&lt;br /&gt;        }&lt;br /&gt;        else if (Touch2ID == 0)&lt;br /&gt;        {&lt;br /&gt;           Touch2.Visibility = Visibility.Visible;&lt;br /&gt;&lt;br /&gt;           Touch2ID = e.TouchDevice.Id;&lt;br /&gt;           // move the ellipse to the given location&lt;br /&gt;           Touch2.SetValue(Canvas.LeftProperty, p.Position.X - Touch2.Width / 2);&lt;br /&gt;           Touch2.SetValue(Canvas.TopProperty, p.Position.Y - Touch2.Height / 2);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private void Window_TouchMove(object sender, TouchEventArgs e)&lt;br /&gt;    {&lt;br /&gt;        TouchPoint p = e.GetTouchPoint(this);&lt;br /&gt;        // determine which contact this belongs to&lt;br /&gt;        if (Touch1ID == e.TouchDevice.Id)&lt;br /&gt;        {&lt;br /&gt;           Touch1.SetValue(Canvas.LeftProperty, p.Position.X - Touch1.Width / 2);&lt;br /&gt;           Touch1.SetValue(Canvas.TopProperty, p.Position.Y - Touch1.Height / 2);&lt;br /&gt;        }&lt;br /&gt;        else if (Touch2ID == e.TouchDevice.Id)&lt;br /&gt;        {&lt;br /&gt;           Touch2.SetValue(Canvas.LeftProperty, p.Position.X - Touch2.Width / 2);&lt;br /&gt;           Touch2.SetValue(Canvas.TopProperty, p.Position.Y - Touch2.Height / 2);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private void Window_TouchUp(object sender, TouchEventArgs e)&lt;br /&gt;    {&lt;br /&gt;        if (e.TouchDevice.Id == Touch1ID)&lt;br /&gt;        {&lt;br /&gt;            Touch1.Visibility = Visibility.Hidden;&lt;br /&gt;&lt;br /&gt;            Touch1ID = 0;&lt;br /&gt;        }&lt;br /&gt;        else if (e.TouchDevice.Id == Touch2ID)&lt;br /&gt;        {&lt;br /&gt;            Touch2.Visibility = Visibility.Hidden;&lt;br /&gt;&lt;br /&gt;            Touch2ID = 0;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;顯示結果如下所示:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6zpKeZQAV5CuIsotIuX_8D3_ai6LWaGqc0mJ9XFnDZM5yyMWpCtMcyOMve2s3WcUJvp6JijtjwM-Cbs2zOpqjhJT0n88fH94pg8sav5lj8OmLsROCSvtc1vmIsbFjhFl2Cjis0rZvGMhw/s1600/touchpoint.png&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 400px; height: 236px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6zpKeZQAV5CuIsotIuX_8D3_ai6LWaGqc0mJ9XFnDZM5yyMWpCtMcyOMve2s3WcUJvp6JijtjwM-Cbs2zOpqjhJT0n88fH94pg8sav5lj8OmLsROCSvtc1vmIsbFjhFl2Cjis0rZvGMhw/s400/touchpoint.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5405698868072142354&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;[圖 1]  Multi-touch points in WPF4.0 Beta 2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;不過目前這些觸控功能在Beta版還是有很多bug, 可參考這些文章測試出來的結果:&lt;br /&gt;&lt;a style=&quot;font-family: arial;&quot; href=&quot;http://geekswithblogs.net/kobush/archive/2009/10/28/135767.aspx&quot;&gt;Multi-touch in WPF4.0 Beta2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a style=&quot;font-family: arial;&quot; href=&quot;http://theclevermonkey.blogspot.com/2009/10/wpf-4-beta-2-expands-multi-touch-api.html&quot;&gt;WPF 4, Beta 2 expands multi-touch API but is buggy&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;參考文章:&lt;br /&gt;&lt;a href=&quot;http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2009/07/06/windows-7-experimenting-with-multi-touch-on-windows-7-part-5.aspx&quot;&gt;Windows 7: Experimenting with Multi-Touch on Windows 7 ( Part 5 ) &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://blog.andreweichacker.com/2009/02/windows-7-multi-touch-using-wpf/&quot;&gt;Windows using Multi-touch using WPF&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://surfacedeveloper.blogspot.com/2009/10/multi-touch-in-wpf-40-and-vs2010.html&quot;&gt;&lt;br /&gt;Multi-touch in WPF4.0 and VS2010&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://blogs.msdn.com/jaimer/archive/2009/11/04/introduction-to-wpf-4-multitouch.aspx&quot;&gt;&lt;br /&gt;Introduction to WPF 4 Multitouch&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ee649090%28VS.100%29.aspx&quot;&gt;Walkthrough: Creating Your First Touch Application&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb613588%28VS.100%29.aspx#touch_and_manipulation&quot;&gt;What&#39;s New in WPF Version 4&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/6338785100408367745/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2009/11/wpf-windows7-multi-touch-part-3.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/6338785100408367745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/6338785100408367745'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2009/11/wpf-windows7-multi-touch-part-3.html' title='WPF + Windows7 Multi-touch (Part 3)'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6zpKeZQAV5CuIsotIuX_8D3_ai6LWaGqc0mJ9XFnDZM5yyMWpCtMcyOMve2s3WcUJvp6JijtjwM-Cbs2zOpqjhJT0n88fH94pg8sav5lj8OmLsROCSvtc1vmIsbFjhFl2Cjis0rZvGMhw/s72-c/touchpoint.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-4483517831513242843</id><published>2009-10-18T22:47:00.000-07:00</published><updated>2009-10-19T01:19:10.855-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Multi-touch"/><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><title type='text'>WPF + Windows7 Multi-touch (Part 2)</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;在 &lt;a href=&quot;http://johnniebooks.blogspot.com/2009/09/wpf-windows7-multi-touch.html&quot;&gt;WPF + Windows7 Multi-touch (Part 1)&lt;/a&gt; 這篇文章中, 我們可以透過 &lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;P/ Invoke &lt;/span&gt;的方式來取得Windows 7 的手勢訊息, 並對物體作手勢操作. &lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;不過當你用這個方法來取得觸控點的資訊時, 你會發現收不到&lt;span style=&quot;font-weight: bold;&quot;&gt;WM_TOUCH &lt;/span&gt;的訊息, 這個是因為&lt;span style=&quot;font-weight: bold;&quot;&gt;WPF&lt;/span&gt;團隊還沒把這部分加進去(這篇&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt; &lt;a href=&quot;http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/a96e9f24-4eca-4520-8158-9ecea164bc57&quot;&gt;WPF Windows 7 Multi-touch&lt;/a&gt;.&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;文章中, &lt;span style=&quot;font-weight: bold;&quot;&gt;WPF&lt;/span&gt;團隊有回答此問題)&lt;br /&gt;&lt;br /&gt;因此, 如果要在&lt;span style=&quot;font-weight: bold;&quot;&gt;WPF&lt;/span&gt;程式中取得觸控點的資訊的話, 就必須採用下面步驟:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;新增一個&lt;/span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&quot;MicrosoftTabletPenServiceProperty&quot;&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;屬性&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;到視窗上&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;                &lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;             IntPtr hWnd = new WindowInteropHelper(this).Handle;&lt;br /&gt;           HwndSource src = HwndSource.FromHwnd(hWnd);&lt;br /&gt;           Win7TouchMethod.SetProp(src.Handle,&lt;br /&gt;                     &quot;MicrosoftTabletPenServiceProperty&quot;,&lt;br /&gt;                      new IntPtr(0x01000000));            &lt;/pre&gt;&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;新增&lt;/span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;StylusDown/StylusUp/StylusMove&lt;/span&gt;的事件, 來處理觸控的相關事件.&lt;/li&gt;&lt;/ul&gt;                 &lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;&lt;br /&gt;        this.StylusDown += new StylusDownEventHandler(Window1_StylusDown);&lt;br /&gt;        this.StylusMove += new StylusEventHandler(Window1_StylusMove);&lt;br /&gt;        this.StylusUp += new StylusEventHandler(Window1_StylusUp);&lt;br /&gt;        &lt;/pre&gt;&lt;br /&gt;下面的範例中, 我們會寫一個&lt;span style=&quot;font-weight: bold;&quot;&gt;WPF&lt;/span&gt;的觸控應用程式, 當有觸控發生時, 畫面上會出現圓點(用來表示觸控點的位置)&lt;br /&gt;&lt;br /&gt;source code如下:&lt;br /&gt;&lt;pre class=&quot;xml&quot; name=&quot;code&quot;&gt;&lt;br /&gt;&amp;lt;Window x:Class=&quot;WPFTouch.Window1&quot;&lt;br /&gt;  xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;&lt;br /&gt;  xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;&lt;br /&gt;  Title=&quot;Window1&quot; Height=&quot;600&quot; Width=&quot;800&quot;&gt;&lt;br /&gt;  &amp;lt;Canvas&amp;gt;&lt;br /&gt;      &amp;lt;Ellipse&lt;br /&gt;          Canvas.Left=&quot;0&quot;&lt;br /&gt;          Canvas.Top=&quot;0&quot;&lt;br /&gt;          Name=&quot;Touch1&quot;&lt;br /&gt;          Stroke=&quot;Black&quot;&lt;br /&gt;          Height=&quot;30&quot;&lt;br /&gt;          Width=&quot;30&quot;&lt;br /&gt;          Fill=&quot;Blue&quot;&lt;br /&gt;          Visibility=&quot;Hidden&quot;/&amp;gt;&lt;br /&gt;   &lt;br /&gt;      &amp;lt;Ellipse&lt;br /&gt;          Canvas.Left=&quot;0&quot;&lt;br /&gt;          Canvas.Top=&quot;0&quot;&lt;br /&gt;          Name=&quot;Touch2&quot;&lt;br /&gt;          Stroke=&quot;Black&quot;&lt;br /&gt;          Height=&quot;30&quot;&lt;br /&gt;          Width=&quot;30&quot;&lt;br /&gt;          Fill=&quot;Green&quot;&lt;br /&gt;          Visibility=&quot;Hidden&quot;/&amp;gt;&lt;br /&gt;  &amp;lt;/Canvas&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/Window&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Windows;&lt;br /&gt;using System.Windows.Controls;&lt;br /&gt;using System.Windows.Input;&lt;br /&gt;using System.Windows.Interop;&lt;br /&gt;using Win7TouchInterop;&lt;br /&gt;&lt;br /&gt;namespace WPFTouch&lt;br /&gt;{&lt;br /&gt;  public partial class Window1 : Window&lt;br /&gt;  {&lt;br /&gt;  &lt;br /&gt;      private int Touch1ID = 0;    // id for first touch contact&lt;br /&gt;      private int Touch2ID = 0;    // id for second touch contact&lt;br /&gt;&lt;br /&gt;      public Window1()&lt;br /&gt;      {&lt;br /&gt;          InitializeComponent();&lt;br /&gt;&lt;br /&gt;          Loaded += new RoutedEventHandler(Window1_Loaded);&lt;br /&gt;&lt;br /&gt;          // Add StylusDown/StylusMove/StylusUp events to handle the touch related events&lt;br /&gt;          this.StylusDown += new StylusDownEventHandler(Window1_StylusDown);&lt;br /&gt;          this.StylusMove += new StylusEventHandler(Window1_StylusMove);&lt;br /&gt;          this.StylusUp += new StylusEventHandler(Window1_StylusUp);&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      void Window1_Loaded(object sender, RoutedEventArgs e)&lt;br /&gt;      {&lt;br /&gt;          IntPtr hWnd = new WindowInteropHelper(this).Handle;&lt;br /&gt;          HwndSource src = HwndSource.FromHwnd(hWnd);&lt;br /&gt;&lt;br /&gt;          Win7TouchMethod.SetProp(src.Handle,&lt;br /&gt;                                   &quot;MicrosoftTabletPenServiceProperty&quot;,&lt;br /&gt;                                   new IntPtr(0x01000000));&lt;br /&gt;  &lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      void Window1_StylusDown(object sender, StylusDownEventArgs e)&lt;br /&gt;      {&lt;br /&gt;          Point p = e.GetPosition(this);   // get the location for this contact&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;          if (Touch1ID == 0)&lt;br /&gt;          {&lt;br /&gt;              // Show the touch point&lt;br /&gt;              Touch1.Visibility = Visibility.Visible;&lt;br /&gt;&lt;br /&gt;              Touch1ID = e.StylusDevice.Id;&lt;br /&gt;           &lt;br /&gt;              // move the ellipse to the given location&lt;br /&gt;              Touch1.SetValue(Canvas.LeftProperty, p.X - Touch1.Width / 2);&lt;br /&gt;              Touch1.SetValue(Canvas.TopProperty, p.Y - Touch1.Height / 2);&lt;br /&gt;          }&lt;br /&gt;          else if (Touch2ID == 0)&lt;br /&gt;          {&lt;br /&gt;              Touch2.Visibility = Visibility.Visible;&lt;br /&gt;&lt;br /&gt;              Touch2ID = e.StylusDevice.Id;&lt;br /&gt;              // move the ellipse to the given location&lt;br /&gt;              Touch2.SetValue(Canvas.LeftProperty, p.X - Touch2.Width / 2);&lt;br /&gt;              Touch2.SetValue(Canvas.TopProperty, p.Y - Touch2.Height / 2);&lt;br /&gt;          }&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      void Window1_StylusMove(object sender, StylusEventArgs e)&lt;br /&gt;      {&lt;br /&gt;          Point p = e.GetPosition(this);&lt;br /&gt;          // determine which contact this belongs to&lt;br /&gt;          if (Touch1ID == e.StylusDevice.Id)&lt;br /&gt;          {&lt;br /&gt;              Touch1.SetValue(Canvas.LeftProperty, p.X - Touch1.Width / 2);&lt;br /&gt;              Touch1.SetValue(Canvas.TopProperty, p.Y - Touch1.Height / 2);&lt;br /&gt;          }&lt;br /&gt;          else if (Touch2ID == e.StylusDevice.Id)&lt;br /&gt;          {&lt;br /&gt;              Touch2.SetValue(Canvas.LeftProperty, p.X - Touch2.Width / 2);&lt;br /&gt;              Touch2.SetValue(Canvas.TopProperty, p.Y - Touch2.Height / 2);&lt;br /&gt;          }&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      void Window1_StylusUp(object sender, StylusEventArgs e)&lt;br /&gt;      {&lt;br /&gt;          if (e.StylusDevice.Id == Touch1ID)&lt;br /&gt;          {&lt;br /&gt;              Touch1.Visibility = Visibility.Hidden;&lt;br /&gt;&lt;br /&gt;              Touch1ID = 0;&lt;br /&gt;          }&lt;br /&gt;          else if (e.StylusDevice.Id == Touch2ID)&lt;br /&gt;          {&lt;br /&gt;              Touch2.Visibility = Visibility.Hidden;&lt;br /&gt;&lt;br /&gt;              Touch2ID = 0;&lt;br /&gt;          }&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;執行畫面如下:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4Nhy3EUcJs1WUIqO-0sde1ktcczZbwulH1Z4cQ4GEyJ6C7VTqA_qhn9uc7ZLruJp9Ix2blAyWC1vMvBBoBx1k9RcP9Crh029qlnQgcmTJTNTki0xUnsHylzFn1rwkhyphenhyphenlnYcUNjixp3J3Q/s1600-h/wpf-touch.png&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 459px; height: 286px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4Nhy3EUcJs1WUIqO-0sde1ktcczZbwulH1Z4cQ4GEyJ6C7VTqA_qhn9uc7ZLruJp9Ix2blAyWC1vMvBBoBx1k9RcP9Crh029qlnQgcmTJTNTki0xUnsHylzFn1rwkhyphenhyphenlnYcUNjixp3J3Q/s400/wpf-touch.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5394217760882166338&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;[圖 1] WPF Touch Application&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;參考文章:&lt;br /&gt;&lt;/span&gt;&lt;a href=&quot;http://blog.andreweichacker.com/2009/02/windows-7-multi-touch-using-wpf/&quot;&gt;Windows 7 Multi-touch using WPF&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/4483517831513242843/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2009/10/wpf-windows7-multi-touch-part-2.html#comment-form' title='2 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/4483517831513242843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/4483517831513242843'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2009/10/wpf-windows7-multi-touch-part-2.html' title='WPF + Windows7 Multi-touch (Part 2)'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4Nhy3EUcJs1WUIqO-0sde1ktcczZbwulH1Z4cQ4GEyJ6C7VTqA_qhn9uc7ZLruJp9Ix2blAyWC1vMvBBoBx1k9RcP9Crh029qlnQgcmTJTNTki0xUnsHylzFn1rwkhyphenhyphenlnYcUNjixp3J3Q/s72-c/wpf-touch.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-6646607183187309876</id><published>2009-10-13T00:28:00.000-07:00</published><updated>2009-10-14T22:06:36.957-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><category scheme="http://www.blogger.com/atom/ns#" term="XAML"/><title type='text'>如何讓WPF控制項產生陰影效果</title><content type='html'>&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;在&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;WPF&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;中可以利用&lt;/span&gt;&lt;a style=&quot;font-family: arial;&quot; href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.media.effects.bitmapeffect.aspx&quot;&gt;BitmapEffect&lt;/a&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;(點陣圖效果), 使控制項呈現一些影像特效;如:  Blur(模糊效果), Shadow(陰影效果), &lt;/span&gt;&lt;span&gt;Bevel(&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;斜面), Emboss(&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;凹凸)和色彩光暈等....&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;在這篇文章中, 我們先來介紹會使控制像看起來比較有立體感的陰影效果.&lt;br /&gt;&lt;br /&gt;由於&lt;span style=&quot;font-weight: bold;&quot;&gt;BitmapEffect&lt;/span&gt; 是&lt;span style=&quot;font-weight: bold;&quot;&gt; Visual&lt;/span&gt; 物件上的屬性,  因此, 我們可將&lt;span style=&quot;font-weight: bold;&quot;&gt;BitmapEffect&lt;/span&gt;套用至任何視覺物件(例如 Button,Image, DrawingVisual 或 UIElement)上. 例如我們可以利用&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.media.effects.dropshadowbitmapeffect.aspx&quot;&gt;DropShadowBitmapEffect&lt;/a&gt; 物件建立 &lt;span style=&quot;font-weight: bold;&quot;&gt;WPF&lt;/span&gt; 物件的各種下拉式陰影效果.&lt;br /&gt;&lt;br /&gt;它提供下列屬性來讓你自訂陰影效果:&lt;br /&gt;&lt;ul  style=&quot;font-family:arial;&quot;&gt;&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt;Color&lt;/span&gt; - 設定陰影的顏色&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt;Opacity&lt;/span&gt; - 設定陰影的透明度, 設定範圍為0 至1, 預設值是1&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt;ShadowDepth&lt;/span&gt; - 控制陰影的寬,有效值的範圍為 0 至 300。預設值為 5&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt;Direction&lt;/span&gt; - 控制陰影的方向。請將這個屬性的方向值設定為介於 0 與 360 之間的度數. 0表示陰影會顯示在物件的正右方, 隨著Direction的增加, 陰影會逆時針方向移動&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt;Softness  &lt;/span&gt;- 控制陰影的柔和度或模糊,值 0.0 表示沒有模糊，而值 1.0 則表示全部模糊&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;下面的範例中, 我們將圖1透過&lt;/span&gt;&lt;a href=&quot;http://www.blogger.com/&amp;amp;%7E%7ESPECIAL_REMOVE%21#%7E%7Elt;Image%20Source=%22tulips.jpg%22%20HorizontalAlignment=%22Center%22%20VerticalAlignment=%22Center%22%20Margin=%2280,%2050,%2080,%2050%22%20Name=%22image1%22%20Stretch=%22Fill%22%20&amp;amp;%7E%7ESPECIAL_REMOVE%21#%7E%7Egt;%20&amp;amp;%7E%7ESPECIAL_REMOVE%21#%7E%7Elt;Image.BitmapEffect&amp;amp;%7E%7ESPECIAL_REMOVE%21#%7E%7Egt;%20&amp;amp;%7E%7ESPECIAL_REMOVE%21#%7E%7Elt;DropShadowBitmapEffect%20ShadowDepth=%2220%22%20Direction=%22300%22%20Color=%22Black%22%20Opacity=%220.5%22%20Softness=%220.25%22%20/&amp;amp;%7E%7ESPECIAL_REMOVE%21#%7E%7Egt;%20&amp;amp;%7E%7ESPECIAL_REMOVE%21#%7E%7Elt;/Image.BitmapEffect&amp;amp;%7E%7ESPECIAL_REMOVE%21#%7E%7Egt;%20&amp;amp;%7E%7ESPECIAL_REMOVE%21#%7E%7Elt;/Image&amp;amp;g&quot;&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.media.effects.dropshadowbitmapeffect.aspx&quot;&gt;DropShadowBitmapEffect&lt;/a&gt; 的效果&lt;span style=&quot;font-family:arial;&quot;&gt;, 產生出如圖片2的陰影效果:&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;XAML檔如下所示:&lt;br /&gt;&lt;pre class=&quot;XML&quot; name=&quot;code&quot;&gt;&lt;br /&gt;&amp;lt;Image Source=&quot;tulips.jpg&quot;&lt;br /&gt;       HorizontalAlignment=&quot;Center&quot;&lt;br /&gt;       VerticalAlignment=&quot;Center&quot;&lt;br /&gt;       Margin=&quot;80, 50, 80, 50&quot;&lt;br /&gt;       Name=&quot;image1&quot;&lt;br /&gt;       Stretch=&quot;Fill&quot; &amp;gt;&lt;br /&gt;    &amp;lt;Image.BitmapEffect&amp;gt;&lt;br /&gt;          &amp;lt;DropShadowBitmapEffect ShadowDepth=&quot;20&quot;&lt;br /&gt;                                  Direction=&quot;300&quot;&lt;br /&gt;                                  Color=&quot;Black&quot;&lt;br /&gt;                                  Opacity=&quot;0.5&quot;&lt;br /&gt;                                  Softness=&quot;0.25&quot; /&amp;gt;                                   &lt;br /&gt;    &amp;lt;/Image.BitmapEffect&amp;gt;&lt;br /&gt;&amp;lt;/Image&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a style=&quot;font-family: arial;&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4Lnmdin13lihoTPxJPh28XYqrlnX_aFXiVAbEsT4SeYuB2kp2Paq8oLU0Cf45rO5O9LqJoB0Cula-j37xNpdp2wEnZ5ICkm-swijy4kFWbEnZTMUSUQ_91xKek8To6DrLxez2KFj_J368/s1600-h/original.png&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 400px; height: 269px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4Lnmdin13lihoTPxJPh28XYqrlnX_aFXiVAbEsT4SeYuB2kp2Paq8oLU0Cf45rO5O9LqJoB0Cula-j37xNpdp2wEnZ5ICkm-swijy4kFWbEnZTMUSUQ_91xKek8To6DrLxez2KFj_J368/s400/original.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5391987132972585810&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;[圖1]沒有陰影效果&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a style=&quot;font-family: arial;&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMImOwzLaOvU_XKVsQ9Qv-wZV2IeX1Nej1ytfcI4-TEj1XO3YIUzJPU97RrnYJn0fsADhXw8IEGieg_VnJZHXv1dTWbCDEJRr6eha1-UQfcPvgoCIwbEZwxTIFFY272Ql1L9qxNAYqbYPr/s1600-h/shadow.png&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 400px; height: 269px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMImOwzLaOvU_XKVsQ9Qv-wZV2IeX1Nej1ytfcI4-TEj1XO3YIUzJPU97RrnYJn0fsADhXw8IEGieg_VnJZHXv1dTWbCDEJRr6eha1-UQfcPvgoCIwbEZwxTIFFY272Ql1L9qxNAYqbYPr/s400/shadow.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5391987129705401890&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;[圖2]加上陰影效果&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: rgb(255, 0, 0); font-weight: bold;font-family:arial;&quot; &gt;需要注意的地方:&lt;br /&gt;&lt;/span&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;WPF 點陣圖效果是在軟體模式中呈現. 而且是由UI執行緒執行, 而不是呈現的執行緒, 因此使用點陣圖效果會對效能有很大的影響(效能和元素的數量成正比),  所以最好在少量而且是靜態的內容才使用這些效果. 尤其在大型視覺物件上使用點陣圖效果, 或者以點陣圖效果的屬性建立動畫時, 效能會降低最多.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;參考文章 :&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/ms743435.aspx&quot;&gt;MSDN - 點陣圖效果概觀&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/ms748273.aspx&quot;&gt;MSDN - 建立含陰影的文字&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/6646607183187309876/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2009/10/wpf.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/6646607183187309876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/6646607183187309876'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2009/10/wpf.html' title='如何讓WPF控制項產生陰影效果'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4Lnmdin13lihoTPxJPh28XYqrlnX_aFXiVAbEsT4SeYuB2kp2Paq8oLU0Cf45rO5O9LqJoB0Cula-j37xNpdp2wEnZ5ICkm-swijy4kFWbEnZTMUSUQ_91xKek8To6DrLxez2KFj_J368/s72-c/original.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-812417614213793842</id><published>2009-09-23T23:07:00.000-07:00</published><updated>2010-11-26T01:25:24.394-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>C# - Delgate(委派)和Event(事件)</title><content type='html'>&lt;span style=&quot;font-family: arial;&quot;&gt;首先, 先來釐清&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/ms173171%28VS.80%29.aspx&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Delgate&lt;/span&gt;&lt;/a&gt;和&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/awbftdfh%28VS.80%29.aspx&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Event&lt;/span&gt;&lt;/a&gt;的不同之處&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Delegate &lt;/span&gt;: 類似C語言中的函數指標(function pointer), &lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;它包含了一個函数的原型(參數,返回值,呼叫方式)和該函数的内存位址.&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt; &lt;span style=&quot;color: #000099;&quot;&gt;delegate&lt;/span&gt;是一種型別(class), 要宣告後才能使用.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;例如, &lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;我們在C語言中定義一個 callback函式, 可寫成: &lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;typedef void (_stdcall* TouchFunc) (tOTM_Touch Touch);
&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt; 等同於下面C#的寫法:&lt;/span&gt;  &lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;delegate void TouchEventFunc (tOTM_Touch Touch); &lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Event&lt;/span&gt;: &lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;color: #000099;&quot;&gt;event&lt;/span&gt;是C#是關鍵字, 這個關鍵字是一個修飾詞, 類似&lt;span style=&quot;color: #000099;&quot;&gt;const,static&lt;/span&gt;等&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;, 而&lt;span style=&quot;color: #000099;&quot;&gt;event&lt;/span&gt;是用來修飾&lt;span style=&quot;color: #000099;&quot;&gt;delegate&lt;/span&gt;. Event的實現需要透過&lt;span style=&quot;color: #000099;&quot;&gt;delegate&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;  &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;一個&lt;span style=&quot;color: #000099;&quot;&gt;delegate&lt;/span&gt;被宣告為&lt;span style=&quot;color: #000099;&quot;&gt;event&lt;/span&gt;(事件)後，除了在宣告事件的類別(Publisher)外,&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;在其他的地方,只能利用&lt;span style=&quot;color: red; font-weight: bold;&quot;&gt;+=&lt;/span&gt;、&lt;span style=&quot;color: red; font-weight: bold;&quot;&gt;-=&lt;/span&gt;操作(即subscrib或unsubscribe), 而&lt;span style=&quot;color: #000099;&quot;&gt;delegate&lt;/span&gt;則沒有這樣的限制&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
若要訂閱某事件, 可利用“+=&quot;, 訂閱或註冊某事件指定的&lt;span style=&quot;color: #000099;&quot;&gt;delegate&lt;/span&gt;(所代理的函数). &lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;publisher.RaiseCustomEvent += new CustomEventHandler(HandleCustomEvent);&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;    或&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;publisher.RaiseCustomEvent += HandleCustomEvent; //C# 2.0 內新增的語法
&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;若要取消訂閱事件, 使用減法指派運算子 (-=) ：&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;publisher.RaiseCustomEvent -= HandleCustomEvent;
&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;color: #000099;&quot;&gt;event&lt;/span&gt;為物件提供一種方式, 可在某些事情發生時,通知其他類別或物件.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;傳送或引發事件的類別稱為&lt;span style=&quot;font-weight: bold;&quot;&gt; Publisher&lt;/span&gt;(發行者)&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt; ,而接收或處理事件的類別則稱為&lt;span style=&quot;font-weight: bold;&quot;&gt;Subscriber&lt;/span&gt;(訂閱者)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
跟&lt;span style=&quot;font-weight: bold;&quot;&gt;Method&lt;/span&gt;(方法)不一樣的地方:&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;Event&lt;/span&gt;是主動, 有事件發生就作通知，你可以訂閱或不訂閱&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;; 而&lt;span style=&quot;font-weight: bold;&quot;&gt;Method&lt;/span&gt;是被動, 只能等待來呼叫，你不呼叫它就不會執行 &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;       &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;下面為在C#中使用自訂&lt;span style=&quot;font-weight: bold;&quot;&gt;Event&lt;/span&gt;的步驟:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: arial; font-weight: bold;&quot;&gt;在Publisher Class(傳送事件的類別)&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;color: #000099; font-family: arial;&quot;&gt;宣告事件的Delegate型別&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;public delegate void ChangedEventHandler(object sender, CustomEventArgs e);
&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;
&lt;ul style=&quot;color: #000099;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;宣告事件&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;public event ChangedEventHandler Changed;
&lt;/pre&gt;&lt;br /&gt;
&lt;ul style=&quot;color: #000099;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;當事件發生時,觸發此事件&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;if (Changed != null)
Changed(this, e);&lt;/pre&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial; font-weight: bold;&quot;&gt;在Subscriber Class(接收或處理事件的類別)&lt;/span&gt;&lt;br /&gt;
&lt;ul style=&quot;color: #000099;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;訂閱Publisher Class的事件&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;  &lt;/span&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;         將&lt;span style=&quot;font-weight: bold;&quot;&gt;Delegate&lt;/span&gt;與&lt;span style=&quot;font-weight: bold;&quot;&gt;Event&lt;/span&gt;關聯, 並且註冊這個&lt;span style=&quot;color: #000099;&quot;&gt;event&lt;/span&gt;的EventHandler函式&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;List.Changed += new ChangedEventHandler(ListChanged);&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;
&lt;ul style=&quot;color: #000099;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;自訂事件發生時要作的動作&lt;/span&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;public void ListChanged(object sender, CustomEventArgs e)
{
// Do something....
}
&lt;/pre&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;br /&gt;
下面的sample code 為時間變更事件的範例, 出處為&lt;a href=&quot;http://www.akadia.com/services/dotnet_delegates_and_events.html&quot;&gt; Delegates and Events in C# / .NET &lt;/a&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;using System;
using System.Threading;

namespace EventSample
{
/* ======== Event Publisher ============ */
// Our subject -- it is this class that other classes
// will observe. This class publishes one event:
// SecondChange. The observers subscribe to that event.
public class Clock
{
// Private Fields holding the hour, minute and second
private int _hour;
private int _minute;
private int _second;

// The delegate named SecondChangeHandler,
// which will encapsulate
// any method that takes a clock object
// and a TimeInfoEventArgs
// object as the parameter and returns no value. It&#39;s the
// delegate the subscribers must implement.
public delegate void SecondChangeHandler(
object clock,
TimeInfoEventArgs timeInformation
);

// The event we publish
public event SecondChangeHandler SecondChange;

// The method which fires the Event
protected void OnSecondChange(
object clock,
TimeInfoEventArgs timeInformation
)
{
// Check if there are any Subscribers
if (SecondChange != null)
{
// Call the Event
SecondChange(clock, timeInformation);
}
}

// Set the clock running, it will raise an
// event for each new second
public void Run()
{
for (; ; )
{
// Sleep 1 Second
Thread.Sleep(1000);

// Get the current time
System.DateTime dt = System.DateTime.Now;

// If the second has changed
// notify the subscribers
if (dt.Second != _second)
{
// Create the TimeInfoEventArgs object
// to pass to the subscribers
TimeInfoEventArgs timeInformation =
new TimeInfoEventArgs(
dt.Hour, dt.Minute, dt.Second);

// If anyone has subscribed, notify them
OnSecondChange(this, timeInformation);
}

// update the state
_second = dt.Second;
_minute = dt.Minute;
_hour = dt.Hour;

}
}
}

// The class to hold the information about the event
// in this case it will hold only information
// available in the clock class, but could hold
// additional state information
public class TimeInfoEventArgs : EventArgs
{
public TimeInfoEventArgs(int hour, int minute, int second)
{
this.hour = hour;
this.minute = minute;
this.second = second;
}
public readonly int hour;
public readonly int minute;
public readonly int second;
}

/* ==== Event Subscribers ======= */

// An observer. DisplayClock subscribes to the
// clock&#39;s events. The job of DisplayClock is
// to display the current time
public class DisplayClock
{
// Given a clock, subscribe to
// its SecondChangeHandler event
public void Subscribe(Clock theClock)
{
theClock.SecondChange +=
new Clock.SecondChangeHandler(TimeHasChanged);
}

// The method that implements the
// delegated functionality
public void TimeHasChanged(
object theClock, TimeInfoEventArgs ti)
{
Console.WriteLine(&quot;Current Time: {0}:{1}:{2}&quot;,
ti.hour.ToString(),
ti.minute.ToString(),
ti.second.ToString());
}
}
/* ======= Test Application ========== */

// Test Application which implements the
// Clock Notifier - Subscriber Sample
public class Test
{
public static void Main()
{
// Create a new clock
Clock theClock = new Clock();

// Create the display and tell it to
// subscribe to the clock just created
DisplayClock dc = new DisplayClock();
dc.Subscribe(theClock);

// Get the clock started
theClock.Run();
}
}
}
&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;
下面圖是為執行結果:&lt;br /&gt;
&lt;/span&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7ID6hWShp8Ic-PGcpjQeBmpyw9Efq0Yh2MNshgKTTCKhWm_mLACRFJlgNvKD2qriURkK-cXvvtWxODY3WZdUIIDrpRjQVxquLIYbMSsEhXxC3qY-hX0QH-iwgQWbEfcAGjdrQcFDVKhfy/s1600-h/time.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;640&quot; id=&quot;BLOGGER_PHOTO_ID_5384925387407888194&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7ID6hWShp8Ic-PGcpjQeBmpyw9Efq0Yh2MNshgKTTCKhWm_mLACRFJlgNvKD2qriURkK-cXvvtWxODY3WZdUIIDrpRjQVxquLIYbMSsEhXxC3qY-hX0QH-iwgQWbEfcAGjdrQcFDVKhfy/s640/time.png&quot; width=&quot;597&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
參考文章:&lt;br /&gt;
&lt;a href=&quot;http://www.yoda.arachsys.com/csharp/events.html&quot;&gt;Delegates and events&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa645739%28VS.71%29.aspx&quot;&gt;MSDN - Events Tutorial&lt;/a&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/812417614213793842/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2009/09/c-delgateevent.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/812417614213793842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/812417614213793842'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2009/09/c-delgateevent.html' title='C# - Delgate(委派)和Event(事件)'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7ID6hWShp8Ic-PGcpjQeBmpyw9Efq0Yh2MNshgKTTCKhWm_mLACRFJlgNvKD2qriURkK-cXvvtWxODY3WZdUIIDrpRjQVxquLIYbMSsEhXxC3qY-hX0QH-iwgQWbEfcAGjdrQcFDVKhfy/s72-c/time.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-7747612228510277809</id><published>2009-09-02T02:28:00.000-07:00</published><updated>2010-11-26T01:27:29.955-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Multi-touch"/><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><title type='text'>WPF + Windows7 Multi-touch(Part 1)</title><content type='html'>&lt;span style=&quot;font-family: arial;&quot;&gt;在&lt;span style=&quot;font-weight: bold;&quot;&gt;Win32&lt;/span&gt;的程式中, 可以利用&lt;/span&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms633573%28VS.85%29.aspx&quot;&gt;&lt;span style=&quot;font-family: arial; font-weight: bold;&quot;&gt;WndProc&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;來接收&lt;span style=&quot;font-weight: bold;&quot;&gt;WM_TOUCH / WM_GESTURE&lt;/span&gt; 訊息, 來得到觸控點和手勢的資訊(可參考這兩篇文章&lt;/span&gt;&lt;a href=&quot;http://johnniebooks.blogspot.com/2009/06/windows-touch-sdk-get-touch-point.html&quot;&gt;Get Touch Point&lt;/a&gt; ,  &lt;a href=&quot;http://johnniebooks.blogspot.com/2009/06/windows-7-gesture-sample.html&quot;&gt;Windows 7 Gesture Sample&lt;/a&gt;), 可是在&lt;span style=&quot;font-weight: bold;&quot;&gt;WPF&lt;/span&gt;中沒有&lt;span style=&quot;font-weight: bold;&quot;&gt;WndProc&lt;/span&gt;函式可以呼叫, 因此, 下面的文章將介紹如何在WPF Window上使用Windows 7 Multi-Touch function.&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;/span&gt; &lt;/div&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;在WPF Window使用Windows Touch SDK的步驟如下:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Step 1:  利用PInvoke的機制呼叫user32.dll中定義Touch / Gesture的資料型態, 結構和方法&lt;br /&gt;
&lt;/span&gt;此方法可參考這篇文章&lt;/span&gt; :&lt;a href=&quot;http://johnniebooks.blogspot.com/2009/08/cunmanaged-dll.html&quot;&gt; 如何在C#中使用Unmanaged dll&lt;/a&gt; &lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;br /&gt;
例如;我們要使用&lt;span style=&quot;font-weight: bold;&quot;&gt;Winuser.h&lt;/span&gt;的 &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd317326%28VS.85%29.aspx&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;RegisterTouchWindow&lt;/span&gt;&lt;/a&gt;函式, 其轉換如下:&lt;br /&gt;
&lt;br /&gt;
C&lt;br /&gt;
&lt;pre class=&quot;c&quot; name=&quot;code&quot;&gt;BOOL WINAPI RegisterTouchWindow(
__in  HWND hWnd,
__in  ULONG ulFlags
);

&lt;/pre&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;C#&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;[Flags, Serializable]
public enum RegisterTouchFlags
{
TWF_NONE = 0x00000000,

TWF_FINETOUCH = 0x00000001
}
[DllImport(&quot;user32.dll&quot;, SetLastError = true)]
public static extern bool RegisterTouchWindow(IntPtr hwnd,
[MarshalAs(UnmanagedType.U4)] RegisterTouchFlags flags);
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;span style=&quot;font-family: arial; font-weight: bold;&quot;&gt;&lt;br /&gt;
Step 2: 在WPF Window中利用HwndSource物件來取得的Windows訊息&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;  &lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;由於WPF Window不能像Win32 Window, 可利用&lt;span style=&quot;font-weight: bold;&quot;&gt;WndProc&lt;/span&gt;函式處理&lt;span style=&quot;font-weight: bold;&quot;&gt;WM_TOUCH / WM_GESTURE&lt;/span&gt;訊息,&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;但WPF Window可以用&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.interop.hwndsource.aspx&quot;&gt;HwndSource&lt;/a&gt;來裝載最上層&lt;span style=&quot;font-weight: bold;&quot;&gt;HWND&lt;/span&gt;的所有內容&lt;/span&gt;. &lt;/div&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;br /&gt;
其方法如下;&lt;/span&gt; &lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;br /&gt;
(1) 利用 &lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.interop.windowinterophelper.aspx&quot;&gt;&lt;span style=&quot;color: #000099;&quot;&gt;System.Windows.Interop.WindowInteropHelper&lt;/span&gt;&lt;/a&gt;類別來取得任何WPF Window的&lt;span style=&quot;font-weight: bold;&quot;&gt;HWND&lt;/span&gt;&lt;/span&gt;      &lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;br /&gt;
example:&lt;/span&gt; &lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;span style=&quot;color: #000099;&quot;&gt;  using &lt;/span&gt;System.Windows.Interop;&lt;/span&gt; &lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;span style=&quot;color: #3333ff;&quot;&gt;IntPtr &lt;/span&gt;_hwnd = &lt;span style=&quot;color: #000099;&quot;&gt;new &lt;/span&gt;&lt;span style=&quot;color: #3366ff;&quot;&gt;WindowInteropHelper&lt;/span&gt;(&lt;span style=&quot;color: #000099;&quot;&gt;this&lt;/span&gt;).Handle;&lt;/span&gt;  &lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;br /&gt;
(2) 利用&lt;span style=&quot;font-weight: bold;&quot;&gt;HWND&lt;/span&gt;取得相關的&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.interop.hwndsource.aspx&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;HwndSource&lt;/span&gt;&lt;/a&gt;物件(用&lt;span style=&quot;color: #000099;&quot;&gt;HwndSource.FromHwnd&lt;/span&gt;)&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-family: arial;&quot;&gt;example:&lt;br /&gt;
&lt;/span&gt; &lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;color: #339999;&quot;&gt;HwndSource&lt;/span&gt; src = &lt;span style=&quot;color: #339999;&quot;&gt;HwndSource&lt;/span&gt;.FromHwnd(_hwnd);&lt;/span&gt; &lt;span style=&quot;font-family: arial;&quot;&gt; &lt;/span&gt; &lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;br /&gt;
(3) 利用&lt;span style=&quot;font-weight: bold;&quot;&gt;HwndSource&lt;/span&gt;的&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.interop.hwndsource.addhook.aspx&quot;&gt;AddHook&lt;/a&gt;方法, 即可攔截視窗訊息&lt;/span&gt; &lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;br /&gt;
example:&lt;/span&gt; &lt;span style=&quot;font-family: arial;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;src.AddHook(WndProc);
private IntPtr WndProc( IntPtr hwnd,
int msg,
IntPtr wParam,
IntPtr lParam,
ref bool handled)
{
switch (msg)
{
case TouchMessage.WM_GESTURE:
OnGesture(lParam);
// 記得將handle設為true,告訴系統你已經處理該訊息
handled = true;
break;

default:
break;
}
return IntPtr.Zero;
}
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;  &lt;span style=&quot;font-family: arial;&quot;&gt;     &lt;/span&gt; &lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;看完上面的介紹, 我們就來寫一個 WPF + Win7 Gesture 的應用程式, &lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;我們會在WPF Window上繪製一個rectangle, 並透過一些手勢操作來對此&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;rectangle作放大,縮小,平移,旋轉和改變顏色(twp finger tap)&lt;br /&gt;
&lt;br /&gt;
其步驟如下:&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;首先,我們會寫一個Win7TouchInterop.cs檔, 目的要將&lt;span style=&quot;font-weight: bold;&quot;&gt;Winuser.h&lt;/span&gt;中的 touch和gesture資料作包裝&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;在WPF的程式碼中, 使用&lt;/span&gt;Win7TouchInterop的命名空間&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;span style=&quot;color: #000099;&quot;&gt; using &lt;/span&gt;Win7TouchInterop;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;利用&lt;span style=&quot;font-weight: bold;&quot;&gt;HwndSource&lt;/span&gt;物件來取得的Windows訊息&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;處理手勢訊息&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
程式碼如下所示;&lt;/span&gt;  &lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;br /&gt;
XAML檔&lt;/span&gt;   &lt;span style=&quot;font-family: arial;&quot;&gt;:&lt;br /&gt;
&lt;pre class=&quot;xml&quot; name=&quot;code&quot;&gt;&amp;lt;Window x:Class=&quot;WPFGestureMessage.Window1&quot;
xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
Title=&quot;Touch SDK+WPF&quot; Height=&quot;600&quot; Width=&quot;800&quot;&amp;gt;
&amp;lt;Grid&amp;gt;

&amp;lt;Grid.Resources&amp;gt;
&amp;lt;Storyboard x:Key=&quot;_twoFingerTap&quot;&amp;gt;
&amp;lt;ColorAnimation
Storyboard.TargetName=&quot;rect&quot;
Storyboard.TargetProperty=
&quot;(Rectangle.Fill).(SolidColorBrush.Color)&quot;
From=&quot;SkyBlue&quot;
To=&quot;YellowGreen&quot;
Duration=&quot;00:00:00.5&quot;
AutoReverse=&quot;true&quot;
FillBehavior=&quot;HoldEnd&quot; /&amp;gt;
&amp;lt;/Storyboard&amp;gt;
&amp;lt;/Grid.Resources&amp;gt;

&amp;lt;Rectangle  x:Name=&quot;rect&quot;
RadiusX=&quot;5&quot;
RadiusY=&quot;5&quot;
Width=&quot;300&quot;
Height=&quot;200&quot;
Stroke=&quot;DarkBlue&quot;
StrokeThickness=&quot;5&quot;
Fill=&quot;YellowGreen&quot;
RenderTransformOrigin=&quot;0.5,0.5&quot;&amp;gt;
&amp;lt;Rectangle.RenderTransform&amp;gt;
&amp;lt;TransformGroup&amp;gt;
&amp;lt;ScaleTransform
x:Name=&quot;_scaleTransform&quot;
ScaleX=&quot;1&quot;
ScaleY=&quot;1&quot; /&amp;gt;
&amp;lt;RotateTransform
x:Name=&quot;_rotateTransform&quot;
Angle=&quot;0&quot; /&amp;gt;
&amp;lt;TranslateTransform
x:Name=&quot;_translateTransform&quot;
X=&quot;0&quot;
Y=&quot;0&quot; /&amp;gt;
&amp;lt;/TransformGroup&amp;gt;
&amp;lt;/Rectangle.RenderTransform&amp;gt;
&amp;lt;/Rectangle&amp;gt;

&amp;lt;/Grid&amp;gt;
&amp;lt;/Window&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
C#檔&lt;/span&gt;  &lt;span style=&quot;font-family: arial;&quot;&gt;:&lt;br /&gt;
&lt;pre class=&quot;c&quot; name=&quot;code&quot;&gt;using System;
using System.Windows;

using Win7TouchInterop;
using System.Windows.Interop;
using System.Runtime.InteropServices;
using System.Windows.Media.Animation;

namespace WPFGestureMessage
{
/// &lt;summary&gt;
/// Interaction logic for Window1.xaml
/// &lt;/summary&gt;
public partial class Window1 : Window
{
private IntPtr _hwnd;
const double scaleSensitivityMagicFactor = 200.0;
const double rotateSensitivityMagicFactor = 25.0;

private long _beginScale;

private bool captureAngle;
private double _beginAngle;

private Point firstPoint;

Storyboard _twoFingerTap;

public Window1()
{
InitializeComponent();
Loaded += new RoutedEventHandler(Window1_Loaded);
_twoFingerTap = rect.FindResource(&quot;_twoFingerTap&quot;) as Storyboard;

}

void Window1_Loaded(object sender, RoutedEventArgs e)
{
_hwnd = new WindowInteropHelper(this).Handle;
HwndSource src = HwndSource.FromHwnd(_hwnd);
if (src != null)
src.AddHook(WndProc);

// Setup the gestures
var gConfig = new[]
{
new GESTURECONFIG
{
dwID = GestureID.GID_ALL,

dwWant = WantGestures.GC_ANY
}   
};

Win7TouchMethod.SetGestureConfig(_hwnd,
0,
gConfig.Length,
gConfig,
Marshal.SizeOf(gConfig[0]));
}


private Point ConvertPoint(POINTS pts)
{
var pt = new POINT { X = pts.X, Y = pts.Y };
Win7TouchMethod.ScreenToClient(_hwnd, ref pt);
return new Point(pt.X, pt.Y);
}


private IntPtr WndProc(IntPtr hwnd,
int msg,
IntPtr wParam,
IntPtr lParam,
ref bool handled)
{

switch (msg)
{
case Win7TouchMessages.WM_GESTURE:
OnGesture(lParam);
handled = true;
break;
default:
break;
}


return IntPtr.Zero;
}

private void OnGesture(IntPtr gestureMsg)
{
GESTUREINFO gesture = new GESTUREINFO();
gesture.cbSize = Marshal.SizeOf(gesture);
if (Win7TouchMethod.GetGestureInfo(gestureMsg, out gesture))
{
switch (gesture.dwID)
{
case GestureID.GID_PAN:
OnPan(gesture.dwInstanceID,
ConvertPoint(gesture.ptsLocation),
gesture.dwFlags);
break;
case GestureID.GID_ROTATE:
OnRotate(gesture.ullArguments,
gesture.dwFlags);
break;
case GestureID.GID_TWOFINGERTAP:
_twoFingerTap.Stop();
_twoFingerTap.Begin();
break;
case GestureID.GID_ZOOM:
OnZoom(ConvertPoint(gesture.ptsLocation),
gesture.ullArguments,
gesture.dwFlags);
break;
default:
break;
}
}
Win7TouchMethod.CloseGestureInfoHandle(gestureMsg);
}



private void OnZoom(Point ptCenter,
long scale,
GestureFlags gestureFlags)
{

if ((gestureFlags &amp;amp; GestureFlags.GF_BEGIN) &amp;gt; 0)
{
_beginScale = scale;
}
else
{
double delta = scale - _beginScale;
_beginScale = scale;

double scaleX = (delta / scaleSensitivityMagicFactor);
double scaleY = (delta / scaleSensitivityMagicFactor);

_scaleTransform.ScaleX += scaleX;
_scaleTransform.ScaleY += scaleY;

}
}


private void OnPan(uint id,
Point point,
GestureFlags gestureFlags)
{

if ((gestureFlags &amp;amp; GestureFlags.GF_BEGIN) &amp;gt; 0)
{
firstPoint = point;
}
else
{
Point curPoint = point;
double xDelta = curPoint.X - firstPoint.X;
double yDelta = curPoint.Y - firstPoint.Y;

_translateTransform.X += xDelta;
_translateTransform.Y += yDelta;

firstPoint = curPoint;
}
}

private void OnRotate(double radians,
GestureFlags gestureFlags)
{

double angle = Win7TouchMethod.ROTATE_ANGLE_FROM_ARGUMENT(radians) * (180.0 / Math.PI);
if ((gestureFlags &amp;amp; GestureFlags.GF_BEGIN) &amp;gt; 0)
{
captureAngle = true;
}
else
{
if (captureAngle)
{
_beginAngle = angle;
captureAngle = false;
}
else
{
double delta = angle - _beginAngle;

_rotateTransform.Angle += 0 - (delta / rotateSensitivityMagicFactor);

if ((gestureFlags &amp;amp; GestureFlags.GF_END) &amp;gt; 0)
{
captureAngle = true;
_beginAngle = 0;
}
}
}//end else
}//end
}
}
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
成果如下圖所示:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheX17bW_Iydgu3CT6u4aOvLvQJce81yBNv4AnSOTSmZzRtq3HC7XKuI1UvF4AzMq6wF-8BGSOGPOuybSmxir6VG_rWk6NuuXM6Pt0gB4AylWF75mV2dptJvvbUikayEsK2AWID5kn5waa_/s1600-h/1.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5377052558508262386&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheX17bW_Iydgu3CT6u4aOvLvQJce81yBNv4AnSOTSmZzRtq3HC7XKuI1UvF4AzMq6wF-8BGSOGPOuybSmxir6VG_rWk6NuuXM6Pt0gB4AylWF75mV2dptJvvbUikayEsK2AWID5kn5waa_/s400/1.png&quot; style=&quot;cursor: pointer; height: 300px; width: 400px;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
[圖 1] 初始畫面&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7fQUDhf6dD6t2cK61h_fRx4kjlveb9pDUQeCx3opF0Sn0SWyBgm-g-Y81xiqbs8HbTvjr3yu0UMKu39jJXTp1rzj7vkFhKL7_TcMoSMhSUE0DyNGB32-XwDkiIYy2tXZw5UR-eXI1vzk0/s1600-h/3.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5377052572845675410&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7fQUDhf6dD6t2cK61h_fRx4kjlveb9pDUQeCx3opF0Sn0SWyBgm-g-Y81xiqbs8HbTvjr3yu0UMKu39jJXTp1rzj7vkFhKL7_TcMoSMhSUE0DyNGB32-XwDkiIYy2tXZw5UR-eXI1vzk0/s400/3.png&quot; style=&quot;cursor: pointer; height: 300px; width: 400px;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;[圖 2] 縮小&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih1yFsN4fYB0bhU0EspD2eROAigyOPbXmKMSWKHXuUijEFzwyyQWCYbFVvgUs34pisv_m5d9lXUizAScEtaUu4aILo0Cve1w2PRAOSq9McLTMv8_DgRQy7XI0j7CUXP03UlBv1E_1FS8Wh/s1600-h/2.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5377052569762791266&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih1yFsN4fYB0bhU0EspD2eROAigyOPbXmKMSWKHXuUijEFzwyyQWCYbFVvgUs34pisv_m5d9lXUizAScEtaUu4aILo0Cve1w2PRAOSq9McLTMv8_DgRQy7XI0j7CUXP03UlBv1E_1FS8Wh/s400/2.png&quot; style=&quot;cursor: pointer; height: 299px; width: 400px;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
[圖 3] 放大&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAq7RH6Vg_53I77xOa5B1kxruScuCyA44KIpZhWPcp5SKtnTQti84BdxF0-_yI3GLv3ifFIeP_Vv9V2X8mHcZXvAdyEiGmevwzLtivAVldVmJNixHgfbcKSHtgisxECU3eKYPv7B6T44p8/s1600-h/5.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5377053044315588066&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAq7RH6Vg_53I77xOa5B1kxruScuCyA44KIpZhWPcp5SKtnTQti84BdxF0-_yI3GLv3ifFIeP_Vv9V2X8mHcZXvAdyEiGmevwzLtivAVldVmJNixHgfbcKSHtgisxECU3eKYPv7B6T44p8/s400/5.png&quot; style=&quot;cursor: pointer; height: 301px; width: 400px;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;[圖 3] 平移+inertia (因為有開啟&lt;span style=&quot;font-weight: bold;&quot;&gt;GC_PAN_INERIA&lt;/span&gt;)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVxhx7YgJjHm1CZscfpgJcfBKLfA2V4ged0tCurWDwdfMQ6SSzMNFKG2dZxHecOluX1nvVy3gZXNsb3eW8BgfTBliuWd5EgjKQujsc3-Vq7wDWxXIhQr_jKgV_vvH03nwd-behfImk_sqN/s1600-h/4.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5377053037585553970&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVxhx7YgJjHm1CZscfpgJcfBKLfA2V4ged0tCurWDwdfMQ6SSzMNFKG2dZxHecOluX1nvVy3gZXNsb3eW8BgfTBliuWd5EgjKQujsc3-Vq7wDWxXIhQr_jKgV_vvH03nwd-behfImk_sqN/s400/4.png&quot; style=&quot;cursor: pointer; height: 299px; width: 400px;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;[圖 5] 旋轉&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJpTLHkQ4cZn1vmpWuFdI_9QP9jJyK4EJct4rxI3zGxMPwCsI7pt3btn0WCLfGjUFi17WWNLzPFxwZ8SBnZJxedQ4Cxb1Nr5RqTt7RKdZeBNPkgeDnQyDA0jNpYkI7DSO-o1JE2iB8zS2H/s1600-h/6.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5377053048922093346&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJpTLHkQ4cZn1vmpWuFdI_9QP9jJyK4EJct4rxI3zGxMPwCsI7pt3btn0WCLfGjUFi17WWNLzPFxwZ8SBnZJxedQ4Cxb1Nr5RqTt7RKdZeBNPkgeDnQyDA0jNpYkI7DSO-o1JE2iB8zS2H/s400/6.png&quot; style=&quot;cursor: pointer; height: 300px; width: 400px;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
[圖 6] Two finger tap --&amp;gt;改變顏色&lt;br /&gt;
&lt;br /&gt;
參考文章:&lt;br /&gt;
&lt;a href=&quot;http://blog.andreweichacker.com/2009/02/windows-7-multi-touch-using-wpf/&quot;&gt;Windows 7 Multi-touch Using WPF&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2009/06/18/windows-7-experimenting-with-multi-touch-on-windows-7-part-2.aspx&quot;&gt;Windows 7: Experimenting with Multi-Touch on Windows 7 &lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.interop.windowinterophelper.aspx&quot;&gt;MSDN -WindowInteropHelper 類別&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/7747612228510277809/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2009/09/wpf-windows7-multi-touch.html#comment-form' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/7747612228510277809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/7747612228510277809'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2009/09/wpf-windows7-multi-touch.html' title='WPF + Windows7 Multi-touch(Part 1)'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheX17bW_Iydgu3CT6u4aOvLvQJce81yBNv4AnSOTSmZzRtq3HC7XKuI1UvF4AzMq6wF-8BGSOGPOuybSmxir6VG_rWk6NuuXM6Pt0gB4AylWF75mV2dptJvvbUikayEsK2AWID5kn5waa_/s72-c/1.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-1707455726942759060</id><published>2009-08-27T01:42:00.000-07:00</published><updated>2010-11-26T01:24:06.102-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="DLL"/><title type='text'>如何在C#中使用Unmanaged dll</title><content type='html'>&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;在&lt;b&gt;C#&lt;/b&gt;中可以透過&lt;/span&gt;&lt;span style=&quot;font-size: small; font-weight: bold;&quot;&gt;PInvoke(Platform Invocation Services)&lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;, 呼叫 &lt;b&gt;DLL&lt;/b&gt; 內實作的&lt;/span&gt;&lt;span style=&quot;font-size: small; font-weight: bold;&quot;&gt;Unmanaged&lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;函式,&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt; 其流程可以參考 &lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/0h9e9t7d%28en-us,VS.71%29.aspx&quot;&gt;MSDN - PInvok的流程圖&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;在&lt;/span&gt;&lt;span style=&quot;font-size: small; font-weight: bold;&quot;&gt;Managed&lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;的程式中使用&lt;/span&gt;&lt;span style=&quot;font-size: small; font-weight: bold;&quot;&gt;Unmanage&lt;b&gt;d&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt; dll&lt;/b&gt;的方法有兩種:&lt;/span&gt; &lt;/div&gt;&lt;ul style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-size: small;&quot;&gt;呼叫&lt;b&gt;DLL&lt;/b&gt;匯出(dllexport)的函式&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size: small;&quot;&gt;呼叫&lt;b&gt;COM&lt;/b&gt;元件上的介面&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;因為, 使用&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/aa288455%28VS.71%29.aspx&quot;&gt;COM Interop&lt;/a&gt;的方式有點複雜, 所以本文章只介紹第一種方法, 若要使用匯出的 &lt;b&gt;DLL &lt;/b&gt;函式(C-Style function), 可分成下面幾個步驟:&lt;/span&gt;&lt;/div&gt;&lt;ul style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-size: small;&quot;&gt;引用&lt;b&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.runtime.interopservices.dllimportattribute%28en-us,VS.71%29.aspx&quot;&gt;DllImport&lt;/a&gt;&lt;/b&gt;所在的名子空間:  &lt;/span&gt;&lt;span style=&quot;color: #000099; font-size: small; font-weight: bold;&quot;&gt;using System.Runtime.InteropServices;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size: small;&quot;&gt;定義類別(例如&lt;/span&gt;&lt;span style=&quot;color: blue; font-size: small;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt; &lt;/span&gt;PlatformInvoke&lt;span style=&quot;font-size: small;&quot;&gt;)包裝要被呼叫的&lt;b&gt;DLL&lt;/b&gt;介面(也就是C/C++中的header檔)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;ul style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;li&gt;&lt;span style=&quot;font-size: small;&quot;&gt;使用 &lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.runtime.interopservices.dllimportattribute%28en-us,VS.71%29.aspx&quot;&gt;&lt;b&gt;DllImport&lt;/b&gt;&lt;/a&gt;來引用&lt;b&gt;DLL&lt;/b&gt;的函式, 並用 &lt;b&gt;static&lt;/b&gt; 和 &lt;b&gt;extern&lt;/b&gt; 來標記函式. 此目的在告訴編譯器該方法與實體物件無關. &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div style=&quot;color: black; font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;b&gt;DllImport&lt;/b&gt;的格式語法如下:&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;color: #009900; font-size: small;&quot;&gt;//將user32.dll換成要使用的DLL檔&amp;nbsp; &lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #339999; font-size: small;&quot;&gt;DllImport&lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;(&quot;user32.dll&quot;), SetLastError = &lt;/span&gt;&lt;span style=&quot;color: #000099; font-size: small;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt;]&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;color: #009900; font-size: small;&quot;&gt;            //換成所需的方法及參數(需要將Unmanaged類型轉成Managed)&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;color: #000099; font-size: small;&quot;&gt;public static extern&lt;/span&gt;&lt;span style=&quot;font-size: small;&quot;&gt; ReturnType FunctionName(type arg); &lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;如下面範例所示:&lt;/span&gt;&lt;/div&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;using System;
using System.Runtime.InteropServices;

class WrapperTest
{
    [DllImport(&quot;msvcrt.dll&quot;)]
    public static extern int puts(string c);

    [DllImport(&quot;msvcrt.dll&quot;)] 
    publlic static extern int _flushall();

    public static void Main() 
    {
        puts(&quot;Test&quot;);
        _flushall();
    }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;&lt;span style=&quot;font-size: small;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;下面表格列出&lt;b&gt;DllImport&lt;/b&gt;的屬性欄位&lt;br /&gt;
&lt;br /&gt;
&lt;table border=&quot;1&quot; cellpadding=&quot;1&quot; cellspacing=&quot;1&quot; height=&quot;642&quot; style=&quot;width: 672px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;名稱&lt;/td&gt;&lt;td&gt;說明&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;BestFitMapping&lt;/td&gt;&lt;td&gt;將 Unicode 字元轉換成 ANSI 字元時, 設定true/false可啟用或停用自動對應行為&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;CallingConvention&lt;/td&gt;&lt;td&gt;CallingConvention 列舉成員, 此欄位的預設值為 WinAPI&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;CharSet&lt;/td&gt;&lt;td&gt;指示用在入口處中的字串參數, 如果未指定 CharSet, 則預設為 CharSet.Auto&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;EntryPoint&lt;/td&gt;&lt;td&gt;指示要呼叫的 DLL 進入點(Entry Point) 的名稱或序數&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ExactSpelling&lt;/td&gt;&lt;td&gt;控制  DllImportAttribute CharSet 欄位是否會導致 Common Language Runtime 搜尋 Unmanaged DLL 以取得不是指定名稱的進入點名稱.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;PreserveSig&lt;/td&gt;&lt;td&gt;指定簽章是否為 Unmanaged 程式碼進入點的直接轉譯, 預設此欄位為 true&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;SetLasrError&lt;/td&gt;&lt;td&gt;指示自屬性方法傳回之前, 被呼叫端是否呼叫 SetLastError Win32 API 函式。&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ThrowOnUnmappableChar&lt;/td&gt;&lt;td&gt;&lt;span sdata=&quot;memberAuthoredSummary&quot;&gt;在無法對應的 Unicode 字元轉換為 ANSI &quot;?&quot; 字元時, 啟用或停用例外狀況的擲回&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;以&lt;span style=&quot;font-weight: bold;&quot;&gt; Managed&lt;/span&gt; 資料型別代替 &lt;span style=&quot;font-weight: bold;&quot;&gt;Unmanaged &lt;/span&gt;資料型別&lt;/li&gt;
&lt;/ul&gt;Managed需要封裝Unmanaged的資料, 下面表格列出&lt;span style=&quot;font-weight: bold;&quot;&gt;Unmanaged&lt;/span&gt;和&lt;span style=&quot;font-weight: bold;&quot;&gt;Managed&lt;/span&gt;的資料型態轉換:&lt;br /&gt;
&lt;table border=&quot;1&quot; cellpadding=&quot;1&quot; cellspacing=&quot;1&quot; height=&quot;543&quot; style=&quot;width: 702px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Wtypes.h 中的 Unmanaged 型別&lt;/td&gt;&lt;td&gt;Unmanaged C 語言型別&lt;/td&gt;&lt;td&gt;Managed 類別名稱&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;HANALE&lt;/td&gt;&lt;td&gt;void*&lt;/td&gt;&lt;td&gt;System.IntPtr&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;BYTE&lt;/td&gt;&lt;td&gt;unsigned char&lt;/td&gt;&lt;td&gt;System.Byte&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;SHORT&lt;/td&gt;&lt;td&gt;short&lt;/td&gt;&lt;td&gt;System.Int16&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;WORD&lt;/td&gt;&lt;td&gt;unsigned short&lt;/td&gt;&lt;td&gt;System.UInt16&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;INT&lt;/td&gt;&lt;td&gt;int&lt;/td&gt;&lt;td&gt;System.Int32&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;UINT&lt;/td&gt;&lt;td&gt;unsigned int&lt;/td&gt;&lt;td&gt;System.UInt32&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;LONG&lt;/td&gt;&lt;td&gt;long&lt;/td&gt;&lt;td&gt;System.Int32&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;BOOL&lt;/td&gt;&lt;td&gt;long&lt;/td&gt;&lt;td&gt;System.Int32&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;DWORD&lt;/td&gt;&lt;td&gt;unsigned long&lt;/td&gt;&lt;td&gt;System.UInt32&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ULONG&lt;/td&gt;&lt;td&gt;unsigned long&lt;/td&gt;&lt;td&gt;System.UInt32&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;CHAR&lt;/td&gt;&lt;td&gt;char&lt;/td&gt;&lt;td&gt;System.Char&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;LPSTR&lt;/td&gt;&lt;td&gt;char*&lt;/td&gt;&lt;td&gt;System.String 或&lt;br /&gt;
System.Text.StringBuilder&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;LPCSTR&lt;/td&gt;&lt;td&gt;Const char*&lt;/td&gt;&lt;td&gt;System.String 或&lt;br /&gt;
System.Text.StringBuilder&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;LPWSTR&lt;/td&gt;&lt;td&gt;wchar_t*&lt;/td&gt;&lt;td&gt;System.String 或&lt;br /&gt;
System.Text.StringBuilder&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;LPCWSTR&lt;/td&gt;&lt;td&gt;Const wchar_t*&lt;/td&gt;&lt;td&gt;System.String 或&lt;br /&gt;
System.Text.StringBuilder&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;FLOAT&lt;/td&gt;&lt;td&gt;Float&lt;/td&gt;&lt;td&gt;System.Single&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;DOUBLE&lt;/td&gt;&lt;td&gt;Double&lt;/td&gt;&lt;td&gt;System.Double&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
如果要包裝一個資料結構, &lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;在 C# 中可以使用 &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute.aspx&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;StructLayout&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;屬性來表示的結構, 如下面範例說明&lt;/span&gt;:&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;C&lt;/th&gt;&lt;th&gt;C#&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;br /&gt;
&lt;pre class=&quot;c&quot; name=&quot;code&quot;&gt;struct tOTM_Point
{
int X;

int Y;

int R;

};
&lt;/pre&gt;&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;&lt;br /&gt;
&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;[Serializable, StructLayout(LayoutKind.Sequential)]
public struct tOTM_Point
{

public int X;

public int Y;

public int R;

}&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/span&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;&lt;br /&gt;
如果在Struct中有Array的型態, 可以利用&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshalasattribute.aspx&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;MarshalAs&lt;/span&gt;&lt;/a&gt; 屬性來表示, 如下所示&lt;br /&gt;
&lt;br /&gt;
&lt;table&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;C&lt;/th&gt;&lt;th&gt;C#&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;br /&gt;
&lt;pre class=&quot;c&quot; name=&quot;code&quot;&gt;struct tOTM_Touch
{
int TouchType;

int TouchState;

tOTM_Point PointArray[2];

};
&lt;/pre&gt;&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;&lt;br /&gt;
&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;[Serializable, StructLayout(LayoutKind.Sequential)]
public struct tOTM_Touch
{

public tOTM_TouchType TouchType;

public tOTM_TouchState TouchState;


[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public tOTM_Point[] PointArray;

};
&lt;/pre&gt;&lt;br /&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
下面我以一個用C寫的OTMUT.dll為例子, 說明如何將Unmanaged dll轉成Managed程式碼:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C&lt;br /&gt;
&lt;pre class=&quot;c&quot; name=&quot;code&quot;&gt;#ifdef  OTMUT_EXPORTS
#define OTMUT_API __declspec(dllexport)
#else
#define OTMUT_API __declspec(dllimport)
#endif


struct tOTM_Point
{
int X;

int Y;

int R;
};

struct tOTM_Touch
{
int TouchType;

int TouchState;

tOTM_Point PointArray[2];
};

typedef void (_stdcall* TouchFunc) (tOTM_Touch Touch);

OTMUT_API void RegisterTouchFunc(TouchFunc Func);

&lt;/pre&gt;&lt;br /&gt;
C#&lt;br /&gt;
&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;using System;
using System.Runtime.InteropServices;


namespace OTMUTInterop
{
[Serializable,
StructLayout(LayoutKind.Sequential)]
public struct tOTM_Point
{   
public int X;

public int Y;

public int R;

};

[Serializable,
StructLayout(LayoutKind.Sequential)]
public struct tOTM_Touch
{    
public tOTM_TouchType TouchType;

public tOTM_TouchState TouchState;

[MarshalAs(UnmanagedType.ByValArray,
SizeConst = 2)]
public tOTM_Point[] PointArray;

};

delegate void
TouchFunc(tOTM_Touch touch);

class OTMUT
{       
[DllImport(&quot;OTMUT.dll&quot;,
CallingConvention =
CallingConvention.StdCall)]
public static extern void
RegisterTouchFunc(TouchFunc func);

}
}
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
參考文章 :&lt;br /&gt;
MSDN - &lt;/span&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/26thfadc.aspx&quot;&gt;使用 Unmanaged DLL 函式&lt;/a&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: arial;&quot;&gt;MSDN -&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/fzhhdwae.aspx&quot;&gt; &lt;/a&gt;&lt;/span&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/fzhhdwae.aspx&quot;&gt;使用平台叫用封送處理資料&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/1707455726942759060/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2009/08/cunmanaged-dll.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/1707455726942759060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/1707455726942759060'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2009/08/cunmanaged-dll.html' title='如何在C#中使用Unmanaged dll'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-4480978576592738097</id><published>2009-08-23T20:08:00.000-07:00</published><updated>2009-09-06T18:34:59.645-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>C#型別轉換(Casting) - as運算子</title><content type='html'>&lt;span style=&quot;font-family:lucida grande;&quot;&gt;當你在C#中作型別轉換時, 可以利用強制轉換的方法, 例如:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style=&quot;margin: 0cm 0cm 0pt 18pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt;double&lt;/span&gt;  dx = 7.3;&lt;/div&gt;&lt;div style=&quot;margin: 0cm 0cm 0pt 18pt;&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt;int&lt;/span&gt; i = (&lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt;int&lt;/span&gt;) dx;&lt;/div&gt;&lt;br /&gt;&lt;span style=&quot;font-family:lucida grande;&quot;&gt;&lt;br /&gt;下面的範例中, 我們在一個控制項(ListBox)的選擇項目事件變更時, 將object(sender)轉型為 ListView.&lt;/span&gt;&lt;br /&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;&lt;br /&gt;void ONListBoxSelectinChange(object sender, SelectionChangedEventArgs args)&lt;br /&gt;{&lt;br /&gt;      // 將object轉型為ListView&lt;br /&gt;     ListView lstView = (ListView)sender;&lt;br /&gt;     int TotalCount = lstView.Items.Count;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt; &lt;span style=&quot;font-family:lucida grande;&quot;&gt;不過當轉型失敗時, 會造成程式當掉, &lt;/span&gt;&lt;span style=&quot;font-family:lucida grande;&quot;&gt;因此你必須使用&lt;span style=&quot;font-weight: bold; color: rgb(0, 0, 153);&quot;&gt;try&lt;/span&gt;和&lt;span style=&quot;font-weight: bold; color: rgb(0, 0, 153);&quot;&gt;catch&lt;/span&gt;來處理例外錯誤(&lt;/span&gt;&lt;span style=&quot;font-family:lucida grande;&quot;&gt;系統會丟出&lt;/span&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.invalidcastexception.aspx&quot;&gt;&lt;span style=&quot;font-weight: bold;font-family:lucida grande;&quot; &gt;InvalidCastException&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family:lucida grande;&quot;&gt;例外狀況&lt;/span&gt;&lt;span style=&quot;font-family:lucida grande;&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;&lt;br /&gt;void ONListBoxSelectinChange(object sender, SelectionChangedEventArgs args)&lt;br /&gt;{&lt;br /&gt;try&lt;br /&gt;{&lt;br /&gt;     ListView lstView = (ListView)sender;&lt;br /&gt;     int TotalCount = lstView.Items.Count;&lt;br /&gt;}&lt;br /&gt;catch (InvalidCastException e)&lt;br /&gt;{&lt;br /&gt;      MessageBox.Show(e.Message);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglKxTzlhgB1b02M6sfi8VHpYjTpGuN_e76l4fCZt0fWVrvSuaB7pj8g8Oa2rxXkDaF3068K3SJPkIB6homEtUc0Bk7rUe7_Yi1umyL-poKOsiQA22NrLQNoNuMjUOHmHAzWvgcFjxd_rlE/s1600-h/e1.png&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 400px; height: 76px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglKxTzlhgB1b02M6sfi8VHpYjTpGuN_e76l4fCZt0fWVrvSuaB7pj8g8Oa2rxXkDaF3068K3SJPkIB6homEtUc0Bk7rUe7_Yi1umyL-poKOsiQA22NrLQNoNuMjUOHmHAzWvgcFjxd_rlE/s400/e1.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5373390410044571506&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;[圖 1] 使用try catch丟出的例外錯誤&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family:lucida grande;&quot;&gt;而在C#中提供一個比較簡單的方法, 就是使用&lt;/span&gt;&lt;span style=&quot;font-weight: bold; color: rgb(0, 0, 153);font-family:lucida grande;&quot; &gt;as&lt;/span&gt;&lt;span style=&quot;font-family:lucida grande;&quot;&gt;運算子, 這樣作會更有效率也很安全, 如果轉型失敗的話, 它會返回&lt;span style=&quot;font-weight: bold;&quot;&gt;null&lt;/span&gt;, 因此, 你可以很容易的來作一些判斷, 如下面的範例所示:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family:lucida grande;&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;&lt;br /&gt;void ONListBoxSelectinChange(object sender, SelectionChangedEventArgs args)&lt;br /&gt;{&lt;br /&gt;        ListView lstView = sender as ListView;&lt;br /&gt;&lt;br /&gt;        if (lstView == null)&lt;br /&gt;        {&lt;br /&gt;            MessageBox.Show(&quot;Could not convert object to ListView&quot;);&lt;br /&gt;        }&lt;br /&gt;        else&lt;br /&gt;        {&lt;br /&gt;            int TotalCount = lstView.Items.Count;&lt;br /&gt;        }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;參考資料:&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/cc488006.aspx&quot;&gt; HOW TO：使用 as 和 is 運算子進行安全轉型 (C# 程式設計手冊)&lt;/a&gt;&lt;br /&gt;                &lt;a href=&quot;http://www.cnblogs.com/edgar-sun/archive/2007/08/19/861801.html&quot;&gt; Effective c# Item3：運算子is或as優於强制轉型&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/4480978576592738097/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2009/08/c-as.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/4480978576592738097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/4480978576592738097'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2009/08/c-as.html' title='C#型別轉換(Casting) - as運算子'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglKxTzlhgB1b02M6sfi8VHpYjTpGuN_e76l4fCZt0fWVrvSuaB7pj8g8Oa2rxXkDaF3068K3SJPkIB6homEtUc0Bk7rUe7_Yi1umyL-poKOsiQA22NrLQNoNuMjUOHmHAzWvgcFjxd_rlE/s72-c/e1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6413948643772751285.post-358421626884578765</id><published>2009-08-19T23:14:00.000-07:00</published><updated>2009-09-02T02:17:40.214-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><title type='text'>WPF ListBox - Beginning</title><content type='html'>&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;&lt;br /&gt;ListBox&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;可以讓使用者能夠從清單選取某個項目, 它&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;是一個項目的控制項, &lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;可以包含物件(object)的集合.&lt;/span&gt;&lt;br /&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;ListBox&lt;/span&gt;繼承自&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.controls.itemscontrol.aspx&quot;&gt;ItemControl&lt;/a&gt;,&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;  它可以透過&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.controls.itemscontrol.items.aspx&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Items&lt;/span&gt;&lt;/a&gt;(型別為&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;object collection&lt;/span&gt;)和&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt; &lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.controls.itemscontrol.itemssource.aspx&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;ItemsSource&lt;/span&gt;&lt;/a&gt;(有實踐&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;IEnumerable&lt;/span&gt;的物件)這兩個屬性 , 來將任何物件放入&lt;span style=&quot;font-weight: bold;&quot;&gt;ListBox&lt;/span&gt;中&lt;/span&gt;, &lt;span style=&quot;font-family:arial;&quot;&gt;如果放入的項目不是&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;UIElement&lt;/span&gt;(例如:數值或string), 則會呼叫物件的&lt;span style=&quot;color: rgb(0, 0, 153);&quot;&gt;ToString()&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;函式&lt;/span&gt;,&lt;/span&gt; 然後將資料放入TextBlock中.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;將物件放入&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;ListBox&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;有兩種方法:&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;利用&lt;span style=&quot;font-weight: bold;&quot;&gt;Items&lt;/span&gt;屬性加入項目(Add)&lt;/li&gt;&lt;/ul&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;下面的程式碼說明利用&lt;span style=&quot;font-weight: bold;&quot;&gt;Items&lt;/span&gt;將任一物件放到&lt;/span&gt;&lt;span style=&quot;font-weight: bold;font-family:arial;&quot; &gt;ListBox&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;中:&lt;br /&gt;&lt;br /&gt;XAML檔如下:&lt;br /&gt;&lt;pre class=&quot;xml&quot; name=&quot;code&quot;&gt;&lt;br /&gt;&amp;lt;Window&lt;br /&gt;x:Class=&quot;ListBoxTemplate.Window1&quot;&lt;br /&gt;xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;&lt;br /&gt;xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;&lt;br /&gt;xmlns:sys=&quot;clr-namespace:System;assembly=mscorlib&quot;&lt;br /&gt;Title=&quot;ListBox&quot; Height=&quot;300&quot; Width=&quot;300&quot;&amp;gt;&lt;br /&gt;&amp;lt;Grid&amp;gt;&lt;br /&gt;&amp;lt;ListBox Margin=&quot;10&quot; Name=&quot;listBox1&quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;ListBoxItem Foreground=&quot;Aqua&quot;&amp;gt;Text&amp;lt;/ListBoxItem&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;ListBoxItem&amp;gt;&lt;br /&gt;        &amp;lt;sys:DateTime&amp;gt;8/20/2009&amp;lt;/sys:DateTime&amp;gt;&lt;br /&gt;    &amp;lt;/ListBoxItem&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;ListBoxItem&amp;gt;&lt;br /&gt;        &amp;lt;Button Content=&quot;Button&quot;&lt;br /&gt;                Background=&quot;LavenderBlush&quot;&lt;br /&gt;                Foreground=&quot;Green&quot;&lt;br /&gt;                Width=&quot;60&quot;&lt;br /&gt;                Height=&quot;30&quot;/&amp;gt;&lt;br /&gt;    &amp;lt;/ListBoxItem&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;ListBoxItem&amp;gt;&lt;br /&gt;        &amp;lt;StackPanel&amp;gt;&lt;br /&gt;            &amp;lt;Rectangle Width=&quot;50&quot;&lt;br /&gt;                       Height=&quot;50&quot;&lt;br /&gt;                       Fill=&quot;Chartreuse&quot;&lt;br /&gt;                       Stroke=&quot;LightSlateGray&quot;&lt;br /&gt;                       StrokeThickness=&quot;3&quot;/&amp;gt;&lt;br /&gt;            &amp;lt;TextBlock Text=&quot;Multiple objects in Panel&quot;&lt;br /&gt;                       FontSize=&quot;16&quot;&lt;br /&gt;                       Foreground=&quot;Red&quot;/&amp;gt;&lt;br /&gt;        &amp;lt;/StackPanel&amp;gt;&lt;br /&gt;    &amp;lt;/ListBoxItem&amp;gt;&lt;br /&gt;&amp;lt;/ListBox&amp;gt;&lt;br /&gt;&amp;lt;/Grid&amp;gt;&lt;br /&gt;&amp;lt;/Window&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;C#檔如下:&lt;br /&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;&lt;br /&gt;Grid grid = new Grid();&lt;br /&gt;ListBox listBox1 = new ListBox();  &lt;br /&gt;listBox1.Margin = new Thickness(10);&lt;br /&gt;&lt;br /&gt;grid.Children.Add(listBox1);&lt;br /&gt;&lt;br /&gt;// Add a string object to a ListBox.&lt;br /&gt;listBox1.Items.Add(&quot;Text&quot;);&lt;br /&gt;&lt;br /&gt;// Add a DateTime object to a ListBox&lt;br /&gt;DateTime dateTime = new DateTime(2009, 8, 20);&lt;br /&gt;listBox1.Items.Add(dateTime);&lt;br /&gt;&lt;br /&gt;// Add a button object to a ListBox&lt;br /&gt;Button button1 = new Button();&lt;br /&gt;button1.Content = &quot;Button&quot;;&lt;br /&gt;button1.Background = Brushes.LavenderBlush;&lt;br /&gt;button1.Foreground = Brushes.Green;&lt;br /&gt;button1.Width = 60;&lt;br /&gt;button1.Height = 30;&lt;br /&gt;listBox1.Items.Add(button1);&lt;br /&gt;&lt;br /&gt;// Add a stackpanel that contains multpile objects to the ListBox.&lt;br /&gt;StackPanel panel = new StackPanel();&lt;br /&gt;&lt;br /&gt;Rectangle rect = new Rectangle();&lt;br /&gt;rect.Width = 50;&lt;br /&gt;rect.Height = 50;&lt;br /&gt;rect.Fill = Brushes.Chartreuse;&lt;br /&gt;rect.Stroke = Brushes.LightSlateGray;&lt;br /&gt;rect.StrokeThickness = 3;&lt;br /&gt;&lt;br /&gt;TextBlock txtBlock = new TextBlock();&lt;br /&gt;txtBlock.Text = &quot;Multiple objects in Panel&quot;;&lt;br /&gt;txtBlock.FontSize = 16;&lt;br /&gt;txtBlock.Foreground = Brushes.Red;&lt;br /&gt;&lt;br /&gt;panel.Children.Add(rect);&lt;br /&gt;panel.Children.Add(txtBlock);&lt;br /&gt;listBox1.Items.Add(panel);&lt;br /&gt;&lt;br /&gt;this.AddChild(grid);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhG8WeL6pa1jya0xWuZxLTX97IiCWkzig0e04XGbsIKUpP7QKOIZZoQMOUstIPRavFz4lqyGBkieNyJhudeKkytdua2beja2n-fOYF9lDndr6M2LngLYTKinQ3VLYTNfsWKe11d-ZG-CLQE/s1600-h/l1.png&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 300px; height: 300px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhG8WeL6pa1jya0xWuZxLTX97IiCWkzig0e04XGbsIKUpP7QKOIZZoQMOUstIPRavFz4lqyGBkieNyJhudeKkytdua2beja2n-fOYF9lDndr6M2LngLYTKinQ3VLYTNfsWKe11d-ZG-CLQE/s400/l1.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5372331451690801474&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;[圖 1] 利用Items加物件&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt; &lt;span style=&quot;font-family:arial;&quot;&gt;將&lt;span style=&quot;font-weight: bold;&quot;&gt;ItemsSource&lt;/span&gt; 繫結到一個物件的集合&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style=&quot;text-align: justify;&quot;&gt;你可以&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span&gt;讓&lt;/span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;ItemsSource&lt;/span&gt;等於一個物件的集合,&lt;/span&gt; 或是將&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;ItemsSource&lt;/span&gt;&lt;/span&gt;繫結(Binding)至集合物件,&lt;br /&gt;注意: 當設定&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;ItemsSource&lt;/span&gt; 屬性設定時, 會將&lt;span style=&quot;font-weight: bold;&quot;&gt;  Items&lt;/span&gt; 集合設為唯讀和固定大小,  &lt;/span&gt;因此不能再對&lt;span style=&quot;font-weight: bold;&quot;&gt;Items&lt;/span&gt;作新增或移除. 若將&lt;span style=&quot;font-weight: bold;&quot;&gt;ItemsSource&lt;/span&gt; 屬性設為 null, 則會移除集合, 並將用法還原為 &lt;span style=&quot;font-weight: bold;&quot;&gt;Items&lt;/span&gt;.&lt;br /&gt;&lt;/div&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;下面的範例說明, 如何利用&lt;span style=&quot;font-weight: bold;&quot;&gt;ItemSource&lt;/span&gt;去&lt;span style=&quot;font-weight: bold;&quot;&gt;Binding&lt;/span&gt;一個物件:&lt;br /&gt;首先, 我們先建立一個&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;WeekData &lt;/span&gt;的物件&lt;/span&gt;,如下:&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt; public class WeekData : ObservableCollection&amp;lt;string&amp;gt;&lt;br /&gt;{&lt;br /&gt;public WeekData()&lt;br /&gt;{&lt;br /&gt;    Add(&quot;Sun&quot;);&lt;br /&gt;    Add(&quot;Mon&quot;);&lt;br /&gt;    Add(&quot;Tue&quot;);&lt;br /&gt;    Add(&quot;Wed&quot;);&lt;br /&gt;    Add(&quot;Thu&quot;);&lt;br /&gt;    Add(&quot;Fri&quot;);&lt;br /&gt;    Add(&quot;Sat&quot;);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;將&lt;span style=&quot;font-weight: bold;&quot;&gt;ItemsSource&lt;/span&gt; 繫結至 WeekData:&lt;br /&gt;&lt;pre class=&quot;c#&quot; name=&quot;code&quot;&gt;&lt;br /&gt;Grid grid = new Grid();&lt;br /&gt;ListBox listBox = new ListBox();&lt;br /&gt;WeekData weekData = new WeekData();&lt;br /&gt;Binding binding = new Binding();&lt;br /&gt;&lt;br /&gt;binding.Source = weekData;&lt;br /&gt;listBox.SetBinding(ListBox.ItemsSourceProperty, binding);&lt;br /&gt;grid.Children.Add(listBox);&lt;br /&gt;this.AddChild(grid);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;如果您想要從 XAML中 繫結的CLR物件, 可以將物件定義為資源, 並指定&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;x:Key&lt;/span&gt;,如下所示:&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;&lt;br /&gt;&lt;pre class=&quot;xml&quot; name=&quot;code&quot;&gt;&lt;br /&gt;&amp;lt;Window.Resources&amp;gt;&lt;br /&gt;&amp;lt;c:WeekData x:Key=&quot;weekData&quot;/&amp;gt;&lt;br /&gt;&amp;lt;/Window.Resources&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;ListBox ItemsSource=&quot;{Binding Source={StaticResource weekData}}&quot;/&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwAWEPzUfsa4KRBjcMa02f5CR9i-Xb1JxHfr6zHzGPKHGTHh_QpotTtXPrVp4PH881jeAY0o_OJfwyRzlgnOAC4bOCUoHbB3VbIUmGZFUDd_S7_Ce_9rSOT5JhRSEmBCVXSrIq9Ww33y_P/s1600-h/l2.png&quot;&gt;&lt;img style=&quot;cursor: pointer; width: 300px; height: 300px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwAWEPzUfsa4KRBjcMa02f5CR9i-Xb1JxHfr6zHzGPKHGTHh_QpotTtXPrVp4PH881jeAY0o_OJfwyRzlgnOAC4bOCUoHbB3VbIUmGZFUDd_S7_Ce_9rSOT5JhRSEmBCVXSrIq9Ww33y_P/s400/l2.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5372339481415648834&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;span style=&quot;color: rgb(255, 0, 0);&quot;&gt;&lt;span style=&quot;color: rgb(0, 0, 0);&quot;&gt;[圖 2] 利用ItemSource加入物件&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;參考文件:&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/bb613556.aspx&quot;&gt;MSDN-&lt;/a&gt;&lt;/span&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/bb613556.aspx&quot;&gt;Controls 內容模型概觀&lt;/a&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.windows.controls.listbox.aspx&quot;&gt;MSDN- ListBox Class&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://johnniebooks.blogspot.com/feeds/358421626884578765/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://johnniebooks.blogspot.com/2009/08/wpf-listbox.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/358421626884578765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6413948643772751285/posts/default/358421626884578765'/><link rel='alternate' type='text/html' href='http://johnniebooks.blogspot.com/2009/08/wpf-listbox.html' title='WPF ListBox - Beginning'/><author><name>Johnnie</name><uri>http://www.blogger.com/profile/07191608395056398292</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xJXG3Uspc6ePM1eiF6jhREyIHTQnRLPcnfVTxZG_vkxHu6bGCFFFdt_wuWVoDwJgGqyjzneCvZJ7EjTENkMxYDvcpReNqNO2TmHmcmWxNaz_xN8G9WYKYa-HMdGeJA/s151/DSCN2718.JPG'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhG8WeL6pa1jya0xWuZxLTX97IiCWkzig0e04XGbsIKUpP7QKOIZZoQMOUstIPRavFz4lqyGBkieNyJhudeKkytdua2beja2n-fOYF9lDndr6M2LngLYTKinQ3VLYTNfsWKe11d-ZG-CLQE/s72-c/l1.png" height="72" width="72"/><thr:total>0</thr:total></entry></feed>