<?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-5699012559868503034</id><updated>2024-12-19T13:05:12.164+08:00</updated><category term="C#"/><category term="WPF"/><category term="XAML"/><category term="UML"/><category term="Blog"/><category term="CSS"/><category term="Windows"/><category term="Form"/><category term="HTML"/><category term="SQL"/><category term="C++"/><category term="DataCenter"/><category term="Encryption"/><category term="License"/><category term="Vitualize"/><title type='text'>Coding James</title><subtitle type='html'>寫程式總會碰到一些有的沒的問題&#xa;好不容易找到答案&#xa;就放出來讓大家一起看吧~</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>85</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-5098790822812922737</id><published>2012-04-04T16:55:00.008+08:00</published><updated>2012-04-04T20:03:29.282+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Encryption"/><title type='text'>在C#中使用RSA加解密</title><content type='html'>RSA是非對稱式加密，金鑰分為公鑰和私鑰兩種，詳情可參考&lt;a href=&quot;http://zh.wikipedia.org/zh-tw/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95&quot;&gt;RSA加密演算法&lt;/a&gt;。一般來說，公鑰會存成.crt，並且撒出去讓大家知道，而私鑰則是存成.pfx，由自己保管，同時加上密碼來保護&lt;br /&gt;&lt;br /&gt;在使用這兩把鑰匙的時候，需先用X509Certificate2物件將其讀出&lt;br /&gt;&lt;code&gt;&lt;br /&gt;using System.Security.Cryptography.X509Certificates;&lt;br /&gt;&lt;br /&gt;RSACryptoServiceProvider LoadPublicKeyFromFile(&lt;br /&gt;    string publicKeyFile)&lt;br /&gt;{&lt;br /&gt;    &lt;n1&gt;///load public key from .crt&lt;/n1&gt;&lt;br /&gt;    X509Certificate2 pubKey =&lt;br /&gt;        new X509Certificate2(publicKeyFile);&lt;br /&gt;&lt;br /&gt;    return (RSACryptoServiceProvider)pubKey.PublicKey.Key;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;RSACryptoServiceProvider LoadPrivateKeyFromFile(&lt;br /&gt;    string privateKeyFile, string password)&lt;br /&gt;{&lt;br /&gt;    &lt;n1&gt;///load private key from .pfx with password&lt;/n1&gt;&lt;br /&gt;    X509Certificate2 priKey =&lt;br /&gt;        new X509Certificate2(privateKeyFile, password);&lt;br /&gt;&lt;br /&gt;    return (RSACryptoServiceProvider)priKey.PrivateKey;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;有時會需要將鑰匙存入資料庫，可以採用XML的格式，RSACryptoServiceProvider有提供很方便的存讀XML字串的函式。&lt;br /&gt;&lt;code&gt;&lt;br /&gt;string ToXmlString(RSACryptoServiceProvider key)&lt;br /&gt;{&lt;br /&gt;    &lt;n1&gt;/// true for private key, false for public key&lt;/n1&gt;&lt;br /&gt;    return key.ToXmlString(true);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;RSACryptoServiceProvider FromXmlString(string xmlString)&lt;br /&gt;{&lt;br /&gt;    RSACryptoServiceProvider key =&lt;br /&gt;        new RSACryptoServiceProvider();&lt;br /&gt;    key.FromXmlString(xmlString);&lt;br /&gt;&lt;br /&gt;    return key;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;注意，不論是公鑰或私鑰皆可以取得一個RSACryptoServiceProvider的物件。實際上在使用RSA加解密演算法時，有時會需要用到私鑰加密，公鑰解密(數位簽章，由自己發給別人，證實該資訊是由我發出)，有時則是公鑰加密，私鑰解密(確認只有自己才可以看的到的文件)，所以這兩把鑰匙的用法是相同的。&lt;br /&gt;&lt;code&gt;&lt;br /&gt;byte[] Encrypt(byte[] rawData, RSACryptoServiceProvider key)&lt;br /&gt;{&lt;br /&gt;    &lt;n1&gt;/// encrypt without OAEP, but PKCS#1 v1.5 padding&lt;/n1&gt;&lt;br /&gt;    return key.Encrypt(rawData, false);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;byte[] Decrypt(byte[] encData, RSACryptoServiceProvider key)&lt;br /&gt;{&lt;br /&gt;    &lt;n1&gt;/// decrypt without OAEP, but PKCS#1 v1.5 padding&lt;/n1&gt;&lt;br /&gt;    return key.Decrypt(rawData, false);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;在這邊使用哪種padding演算法都可以，但是記得加解密的時候需要用同樣的演算法即可。另外，因為加解密時都是採用byte陣列做為原始資料，所以如果原本是string物件的話，可以透過Convert.FromBase64String及Encoding.UTF8.GetString互為轉換。&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/system.security.cryptography.rsacryptoserviceprovider.aspx&quot;&gt;RSACryptoServiceProvider Class&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Optimal_asymmetric_encryption_padding&quot;&gt;Optimal asymmetric encryption padding&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/5098790822812922737/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2012/04/crsa.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/5098790822812922737'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/5098790822812922737'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2012/04/crsa.html' title='在C#中使用RSA加解密'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-879058742522285245</id><published>2012-02-28T21:07:00.015+08:00</published><updated>2012-02-28T23:29:50.150+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DataCenter"/><category scheme="http://www.blogger.com/atom/ns#" term="SQL"/><title type='text'>報告服務(Sql Server Reporting Service, SSRS)的高可用性(High Availability, HA)</title><content type='html'>微軟的資料庫伺服器(Sql Server)提供了報告服務(Reporting Service)，讓客戶可以很容易的產生有關資料庫狀態的報告，像是登入的列表或是某個事件發生的頻率等等。只要有相對應的記錄，都可以用查詢的方式，定期或是依照需求產生報告。有關報告服務的架構可以參考&lt;a href=&quot;http://tech.sina.com.cn/s/2006-09-20/09001148718.shtml&quot;&gt;剖析SQL Server 2005中的報告服務架構&lt;/a&gt;。&lt;br /&gt;&lt;br /&gt;在提供這樣的服務的同時，系統的高可用性也必須涵蓋這部分。報告服務的高可用性可以分成三個方面來考慮，服務，報告服務資料庫，以及查詢資料庫。&lt;br /&gt;&lt;br /&gt;服務的部分比較單純，為了提供高可用性，就多建立幾台報告服務伺服器即可。而查詢資料庫的部分則如同一般資料庫伺服器的高可用性，可以採用叢集(Cluster)或是鏡像(Mirroring)等方式。值得注意的是，由於報告服務的查詢字串有提供故障轉移(Failover Partner)的選項，所以如果採用鏡像的方式時，只需要將備份的伺服器網址填入該欄位，在故障發生時，報告服務就會自動查詢備份的資料庫伺服器，而不會造成服務的中斷。&lt;br /&gt;&lt;br /&gt;最困難的部分在於報告服務資料庫的高可用性。由於在報告服務伺服器端僅能設定一台報告服務伺服器(至少在2008之前尚未提供，可以參考&lt;a href=&quot;http://connect.microsoft.com/SQLServer/feedback/details/166244/reportserver-tempdb-mirror-capability&quot;&gt;ReportServer (TempDB) Mirror capability&lt;/a&gt;)，所以如果採用鏡像的方式，在主伺服器發生故障時，無法自動將設定更新到備份伺服器。&lt;br /&gt;&lt;br /&gt;在這樣的狀況下，第一種選擇是直接將報告服務的資料庫切開，每組報告服務都有自己的資料庫，所以在某一台報告服務+資料庫的伺服器故障時，其他台仍然可以正常運作。但問題是這些資料庫之間沒有同步，所以必須對每個資料庫匯入相同的範本及資料源。同時，報告服務的歷史資料也會散落在各地。&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxMbaUhGQEBg63YiO6Lzgzk1EM0L4eEz49eAOhZrMFc5zNT2mcjtNVEQxV5oCHs7bEw1SCWB9DEBNF1aDwb-ShQtE9fcs3EavUXRJKR7PaJ0aULCFOWP6q9hS-60If1rhLK9gw2VYY_5o/s1600/SSRS1.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 224px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxMbaUhGQEBg63YiO6Lzgzk1EM0L4eEz49eAOhZrMFc5zNT2mcjtNVEQxV5oCHs7bEw1SCWB9DEBNF1aDwb-ShQtE9fcs3EavUXRJKR7PaJ0aULCFOWP6q9hS-60If1rhLK9gw2VYY_5o/s1600/SSRS1.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5714192752531497314&quot; /&gt;&lt;/a&gt;&lt;br /&gt;第二種選擇是純粹的鏡像，將所有的報告服務設定相同的資料庫，如何設定可以參考&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms159114%28v=sql.100%29.aspx&quot;&gt;How to: Configure a Report Server Scale-Out Deployment (Reporting Services Configuration)&lt;/a&gt;。此方法在主要資料庫伺服器故障時，需要手動將報告服務的伺服器設定到備份的伺服器。如果不希望手動，也可以透過代理服務(Agent Service)，在故障發生時，用rsconfig設定報告服務的資料庫。此方法的細節可以參考&lt;a href=&quot;http://www.sqlservercentral.com/articles/Reporting+Services+%28SSRS%29/69699/&quot;&gt;Reporting Services Disaster Recovery&lt;/a&gt;。&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmugBkKI-0VhpQxcs0_dENu2yCH_7IYrSOB17YWZXYzPer4gV1e-Oa3YTTh5APUOmS4QlDjuLWsQ0TlE0506JDBf-po2O-1uAa6jNzzCdGWCaacn9v3QiAj1NC-SHKY0fkcA3Jvys9_e8/s1600/SSRS2.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 228px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmugBkKI-0VhpQxcs0_dENu2yCH_7IYrSOB17YWZXYzPer4gV1e-Oa3YTTh5APUOmS4QlDjuLWsQ0TlE0506JDBf-po2O-1uAa6jNzzCdGWCaacn9v3QiAj1NC-SHKY0fkcA3Jvys9_e8/s1600/SSRS2.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5714196293124534978&quot; /&gt;&lt;/a&gt;&lt;br /&gt;第三種是微軟官方的建議，就是使用叢集的方式，設定可以參考&lt;a href=&quot;http://blog.miniasp.com/post/2010/01/SQL-Server-2008-Failover-Cluster-Installation-Notes-Part-1.aspx&quot;&gt;安裝 SQL Server 2008 容錯轉移叢集心得筆記&lt;/a&gt;。不過在叢集的資料庫伺服器上，無法同時安裝報告服務，也就是說，需要額外的數台伺服器來提供高可用性的報告服務。細節可以參考&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms157293%28v=SQL.100%29.aspx&quot;&gt;Planning a Deployment Topology&lt;/a&gt;。&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuAVfKWXa3UCq7d-DwRooRrfcEWyXMUMh0ug-dZjJjui_SfWIsLWLEDRorEe6-VcPkDAP4NT88ODgOwsWPus1PXTJzJOzeHN_3fi56kPaquPcTa8jyXcMOKqwpB0Sisg8evEpKIRc2zDI/s1600/SSRS3.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 243px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuAVfKWXa3UCq7d-DwRooRrfcEWyXMUMh0ug-dZjJjui_SfWIsLWLEDRorEe6-VcPkDAP4NT88ODgOwsWPus1PXTJzJOzeHN_3fi56kPaquPcTa8jyXcMOKqwpB0Sisg8evEpKIRc2zDI/s1600/SSRS3.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5714207632645431650&quot; /&gt;&lt;/a&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://sqlcat.com/sqlcat/b/technicalnotes/archive/2009/10/23/sql-server-reporting-services-disaster-recovery-case-study.aspx&quot;&gt;SQL Server Reporting Services Disaster Recovery Case Study&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb677365%28v=sql.100%29.aspx&quot;&gt;How to: Configure SharePoint Integration on Multiple Servers&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/879058742522285245/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2012/02/sql-server-reporting-service-ssrshigh.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/879058742522285245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/879058742522285245'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2012/02/sql-server-reporting-service-ssrshigh.html' title='報告服務(Sql Server Reporting Service, SSRS)的高可用性(High Availability, HA)'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxMbaUhGQEBg63YiO6Lzgzk1EM0L4eEz49eAOhZrMFc5zNT2mcjtNVEQxV5oCHs7bEw1SCWB9DEBNF1aDwb-ShQtE9fcs3EavUXRJKR7PaJ0aULCFOWP6q9hS-60If1rhLK9gw2VYY_5o/s72-c/SSRS1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-7659378655224265603</id><published>2012-01-31T16:38:00.004+08:00</published><updated>2012-01-31T18:37:44.146+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Vitualize"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>在虛擬機器(Vitual Machine)中擴充硬碟</title><content type='html'>使用虛擬機器最重要的好處之一，就是可以彈性的擴充硬體&lt;br /&gt;硬體的擴充動作相較於實體機器來說，就少掉了更新硬體這一步驟&lt;br /&gt;(當然要在開虛擬機器的實體機器的硬體限制下)&lt;br /&gt;而Windows在更新CPU或記憶體都是自動完成的&lt;br /&gt;所以在虛擬機器上擴充這兩者都僅僅需要關機，設定，開機三個步驟&lt;br /&gt;&lt;br /&gt;如果是一般的硬碟擴充，只要先在虛擬機器的設定中延伸(Expand)硬碟&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh97b11E_gMLfQAw3p0pwo0LddDUPu9Goqm3TFC27okBFWBhcZfxTl5wxPM47CgPC5P9_1Spyvlfc2-PZhZwA8nEXUMpCavDyxzPjD1Np2sczkqyN79iu8fRO83TVfhFYdiuPBHhiht_TQ/s1600/ExpandDisk.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 351px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh97b11E_gMLfQAw3p0pwo0LddDUPu9Goqm3TFC27okBFWBhcZfxTl5wxPM47CgPC5P9_1Spyvlfc2-PZhZwA8nEXUMpCavDyxzPjD1Np2sczkqyN79iu8fRO83TVfhFYdiuPBHhiht_TQ/s400/ExpandDisk.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5703730816543187922&quot; /&gt;&lt;/a&gt;&lt;br /&gt;再到作業系統裡面使用內建的diskpart將同一個硬碟擴充即可&lt;br /&gt;&lt;output1&gt;&lt;br /&gt;C:\Documents and Settings\Administrator&gt;diskpart&lt;br /&gt;&lt;br /&gt;Microsoft DiskPart version 5.2.3790.3959&lt;br /&gt;Copyright (C) 1999-2001 Microsoft Corporation.&lt;br /&gt;On computer: WIN2K3X86&lt;br /&gt;&lt;br /&gt;DISKPART&gt; list volume&lt;br /&gt;&lt;br /&gt;  Volume ###  Ltr  Label        Fs     Type        Size     Status     Info&lt;br /&gt;  ----------  ---  -----------  -----  ----------  -------  ---------  --------&lt;br /&gt;  Volume 0     C                NTFS   Partition     15 GB  Healthy    System&lt;br /&gt;  Volume 1     D                       CD-ROM          0 B  Healthy&lt;br /&gt;  Volume 2     E   New Volume   NTFS   Partition     20 GB  Healthy&lt;br /&gt;&lt;br /&gt;DISKPART&gt; select volume 2&lt;br /&gt;&lt;br /&gt;Volume 2 is the selected volume.&lt;br /&gt;&lt;br /&gt;DISKPART&gt; extend&lt;br /&gt;&lt;br /&gt;DiskPart successfully extended the volume.&lt;br /&gt;&lt;br /&gt;DISKPART&gt; list volume&lt;br /&gt;&lt;br /&gt;  Volume ###  Ltr  Label        Fs     Type        Size     Status     Info&lt;br /&gt;  ----------  ---  -----------  -----  ----------  -------  ---------  --------&lt;br /&gt;  Volume 0     C                NTFS   Partition     15 GB  Healthy    System&lt;br /&gt;  Volume 1     D                       CD-ROM          0 B  Healthy&lt;br /&gt;* Volume 2     E   New Volume   NTFS   Partition     21 GB  Healthy&lt;br /&gt;&lt;br /&gt;DISKPART&gt;&lt;br /&gt;&lt;br /&gt;&lt;/output1&gt;&lt;br /&gt;另外，在Windows 2003中&lt;br /&gt;因為保護作業系統的檔案，所以無法變更系統磁碟的大小&lt;br /&gt;這時候就需要一點小技巧，在把系統碟延伸後&lt;br /&gt;先將系統碟掛到另外一台機器當作一般磁碟並擴充&lt;br /&gt;此時用原本的虛擬機器開機，就會發現系統磁碟大小已經更改成功了&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://blog.petecheslock.com/2009/04/07/how-to-extend-windows-boot-volumes-in-vmware/&quot;&gt;How to Extend Windows Boot Volumes in VMware&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://chen7768.blogspot.com/2008/08/vmware.html&quot;&gt;如何擴充 VMware 虛擬磁碟及作業系統容量&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/7659378655224265603/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2012/01/vitual-machine.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/7659378655224265603'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/7659378655224265603'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2012/01/vitual-machine.html' title='在虛擬機器(Vitual Machine)中擴充硬碟'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh97b11E_gMLfQAw3p0pwo0LddDUPu9Goqm3TFC27okBFWBhcZfxTl5wxPM47CgPC5P9_1Spyvlfc2-PZhZwA8nEXUMpCavDyxzPjD1Np2sczkqyN79iu8fRO83TVfhFYdiuPBHhiht_TQ/s72-c/ExpandDisk.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-4467419786874627480</id><published>2011-01-07T13:10:00.005+08:00</published><updated>2011-01-07T18:53:58.131+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="License"/><title type='text'>常見開源協議(Open Source License)的比較</title><content type='html'>開放原始碼這樣的想法非常崇高，藉由自由分享各自的程式碼&lt;br /&gt;讓軟體的發展可以更加的快速而且安全&lt;br /&gt;(透明度可以讓全世界一起除錯，而且沒辦法藏後門)&lt;br /&gt;&lt;br /&gt;但是對於&quot;自由&quot;，大家的想法都不太一樣&lt;br /&gt;比如說，如果有人拿你寫的程式去賣錢呢?&lt;br /&gt;這種顧慮會讓很多開發者不願意分享，所以開源協議就出現了&lt;br /&gt;目的就是，讓作者可以在被保護的狀況下&lt;br /&gt;依照期待(選擇的開源協議)的讓全世界的人一起分享&lt;br /&gt;&lt;br /&gt;目前常見的開源協議大都經過&lt;a href=&quot;http://www.opensource.org/&quot;&gt;Open Source Initiative&lt;/a&gt;批准&lt;br /&gt;協議書的全文都可以在&lt;a href=&quot;http://www.opensource.org/licenses/alphabetical&quot;&gt;Open Source Licenses&lt;/a&gt;找到&lt;br /&gt;(從協議的數量就可以看出，這方面也是相當的&quot;自由&quot;)&lt;br /&gt;最常見的有&lt;a href=&quot;http://www.opensource.org/licenses/gpl-3.0&quot;&gt;GPL, GNU General Public License&lt;/a&gt;, &lt;a href=&quot;http://www.opensource.org/licenses/lgpl-3.0&quot;&gt;LGPL, The GNU Lesser General Public License&lt;/a&gt;, &lt;a href=&quot;http://www.opensource.org/licenses/bsd-license&quot;&gt;BSD License&lt;/a&gt;等&lt;br /&gt;這些協議的一個共同點，就是再發佈的時候需要伴隨原有的協議&lt;br /&gt;&lt;br /&gt;其中最嚴厲(崇尚自由，並要求所有人一起崇尚自由)的是GPL&lt;br /&gt;強硬的要求(傳染)所有&quot;引用/修改/衍生&quot;GPL授權的程式碼的軟體&lt;br /&gt;也必須採用GPL授權，並提供未來開發者同樣的自由，包括&lt;br /&gt;1. 以任何目的執行此程式的自由&lt;br /&gt;2. 再發行複製件的自由&lt;br /&gt;3. 改進此程式，並公開發布改進的自由&lt;br /&gt;基於這樣的規定，所以商業軟體或是不打算公開程式碼的軟體&lt;br /&gt;都不得修改甚至引用GPL授權的程式碼&lt;br /&gt;著名的GPL自由軟體包括Linux核心和GCC&lt;br /&gt;&lt;br /&gt;LGPL則是將GPL條件稍微放寬，&lt;br /&gt;如果僅是&quot;引用(Link)&quot;LGPL授權的函式庫&lt;br /&gt;則不需要公開該軟體的程式碼&lt;br /&gt;所以對於商業軟體來說，是可以引用LGPL的函式庫的&lt;br /&gt;但是，對於&quot;修改/衍生&quot;LGPL授權軟體的部分，則同樣必須採用LGPL的授權&lt;br /&gt;也就是一樣需要公開，且提供未來開發者同等的自由&lt;br /&gt;著名的LGPL自由軟體有Mozilla跟OpenOffice.Org&lt;br /&gt;&lt;br /&gt;BSD相對來說就寬鬆的多了&lt;br /&gt;主要差異是在&quot;修改/衍生&quot;BSD授權的軟體時&lt;br /&gt;除了版權聲明中仍需包含原來代碼中的BSD協議以外&lt;br /&gt;開發者有權選擇是否要開放原始碼，或是做為商業用途&lt;br /&gt;&lt;br /&gt;由此可以看出，如果是公司企業打算要使用開放原始碼的授權軟體的時候&lt;br /&gt;BSD授權軟體可以直接使用甚至修改衍生&lt;br /&gt;LGPL授權軟體則是僅能引用(Link)&lt;br /&gt;GPL授權軟體則是儘量不使用，或是規避GPL的授權範圍&lt;br /&gt;例如&lt;a href=&quot;http://www.zdnet.com.tw/enterprise/technology/0,2000085680,20131501,00.htm&quot;&gt;避免GPL風險的另類方法&lt;/a&gt;所提的方法&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://inspire.twgg.org/c/internet/trends/comparison-of-five-kinds-of-standard-open-source-license-bsd-apache-gpl-lgpl-mit.html&quot;&gt;五種開源授權規範的比較 (BSD, Apache, GPL, LGPL, MIT)&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://www.ubuntu-tw.org/modules/newbb/viewtopic.php?post_id=230&quot;&gt;GPL 常見問題&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://www.openfoundry.org/tw/legal-article-/8195-2010-11-22-18-38-45&quot;&gt;自由軟體專案授權方式的轉換（上）：不得撤銷原授權條款&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://www.openfoundry.org/tw/legal-article-/8219-2010-12-24-16-47-06&quot;&gt;自由軟體專案授權方式的轉換（下）：新版本號另以更改後的授權方式釋出&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://www.openfoundry.org/index.php?option=com_content&amp;task=view&amp;id=2138&amp;Itemid=56;isletter=1&quot;&gt;在原始碼之外：編譯與安裝資訊的提供&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://www.openfoundry.org/tw/legal-article-/8119--gpl-&quot;&gt;散佈 GPL 衍生程式所須提供的原始碼範圍&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/4467419786874627480/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2011/01/open-source-license.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/4467419786874627480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/4467419786874627480'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2011/01/open-source-license.html' title='常見開源協議(Open Source License)的比較'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-2970360710846920145</id><published>2010-12-28T14:13:00.005+08:00</published><updated>2010-12-28T16:12:18.713+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>在C#中讀取Excel的試算表</title><content type='html'>在&lt;a href=&quot;http://codingjames.blogspot.com/2010/12/cexcel.html&quot;&gt;取出試算表的名稱&lt;/a&gt;後，就可以針對單一試算表進行讀取&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public List&lt;string&gt; LoadExcelSheet(&lt;br /&gt;    string excelFile, string sheetName)&lt;br /&gt;{&lt;br /&gt;    List&lt;string&gt; dataList = new List&lt;string&gt;();&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// load excel file as an ole database&lt;/n1&gt;&lt;br /&gt;    OleDbConnection excelDatabase =&lt;br /&gt;        new OleDbConnection(string.Format(&lt;br /&gt;            &quot;Provider = Microsoft.Jet.OLEDB.4.0;&quot; +&lt;br /&gt;            &quot;Data Source = {0};&quot; +&lt;br /&gt;            &quot;Extended Properties=&#39;Excel 8.0;HDR=No&#39;&quot;,&lt;br /&gt;            excelFile));&lt;br /&gt;    excelDatabase.Open();&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// query sheet from excel file&lt;/n1&gt;&lt;br /&gt;    OleDbDataAdapter sheetAdapter =&lt;br /&gt;        new OleDbDataAdapter(string.Format(&lt;br /&gt;            &quot;SELECT * FROM [{0}]&quot;, sheetName),&lt;br /&gt;            excelDatabase);&lt;br /&gt;    DataTable fileData = new DataTable();&lt;br /&gt;    sheetAdapter.Fill(fileData);&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// scan all cells in the sheet&lt;/n1&gt;&lt;br /&gt;    foreach (DataRow row in fileData.Rows)&lt;br /&gt;    {&lt;br /&gt;        foreach (object item in row.ItemArray)&lt;br /&gt;        {&lt;br /&gt;            if (&lt;n2&gt;!(item is DBNull)&lt;/n2&gt;)&lt;br /&gt;            {&lt;br /&gt;                dataList.Add(item.ToString());&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// close and release database connection&lt;/n1&gt;&lt;br /&gt;    excelDatabase.Close();&lt;br /&gt;&lt;br /&gt;    return dataList;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;這裡值得注意的是，如果試算表中有些欄位是空的&lt;br /&gt;讀出來的資料會是&lt;n2&gt;DBNull&lt;/n2&gt;的型別，其餘則會是string的型別&lt;br /&gt;&lt;br /&gt;另外，如果是手動輸入試算表名稱的話&lt;br /&gt;要記得在試算表名稱後面加一個$，例如預設的&quot;Sheet1$&quot;&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://catonchuang.blogspot.com/2010/06/c-excel.html&quot;&gt;轉錄 C# 讀取 Excel&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://jian-zhoung.blogspot.com/2008/05/c-excel.html&quot;&gt;C# 讀取 Excel&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.data.datatable_members%28v=VS.80%29.aspx&quot;&gt;DataTable 類別&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/2970360710846920145/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/12/cexcel_28.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/2970360710846920145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/2970360710846920145'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/12/cexcel_28.html' title='在C#中讀取Excel的試算表'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-1769663295046583183</id><published>2010-12-28T13:28:00.005+08:00</published><updated>2010-12-28T14:58:56.410+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>在C#中讀取Excel的試算表名稱</title><content type='html'>在將Excel的檔案當做資料庫的存取的時候&lt;br /&gt;可以先取得檔案中每個試算表的名稱，再做處理&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public List&lt;string&gt; LoadExcelSheetNameList(&lt;br /&gt;    string excelFile)&lt;br /&gt;{&lt;br /&gt;    List&lt;string&gt; sheetNameList = new List&lt;string&gt;();&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// load excel file as an ole database&lt;/n1&gt;&lt;br /&gt;    OleDbConnection excelDatabase =&lt;br /&gt;        new OleDbConnection(string.Format(&lt;br /&gt;            &quot;Provider = Microsoft.Jet.OLEDB.4.0;&quot; +&lt;br /&gt;            &quot;Data Source = {0};&quot; +&lt;br /&gt;            &quot;Extended Properties=&#39;Excel 8.0;HDR=No&#39;&quot;,&lt;br /&gt;            excelFile));&lt;br /&gt;    excelDatabase.Open();&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// load excel sheet as DataRow&lt;/n1&gt;&lt;br /&gt;    DataRow[] sheetList =&lt;br /&gt;        excelDatabase.GetSchema(&quot;Tables&quot;).Select();&lt;br /&gt;    foreach (DataRow sheet in sheetList)&lt;br /&gt;    {&lt;br /&gt;        &lt;n1&gt;/// query each sheet name from excel file&lt;/n1&gt;&lt;br /&gt;        sheetNameList.Add(&lt;br /&gt;            sheet[&quot;TABLE_NAME&quot;] as string);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// close and release database connection&lt;/n1&gt;&lt;br /&gt;    excelDatabase.Close();&lt;br /&gt;&lt;br /&gt;    return sheetNameList;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;在得到名稱後，就可以&lt;a href=&quot;http://codingjames.blogspot.com/2010/12/cexcel_28.html&quot;&gt;針對單一的試算表進行讀取&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://caine.pixnet.net/blog/post/22640051&quot;&gt;[工作] 取得Excel頁籤名稱&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://chchou.pixnet.net/blog/post/27330657&quot;&gt;如何取得 Excel 中的 Sheet Name&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/1769663295046583183/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/12/cexcel.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/1769663295046583183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/1769663295046583183'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/12/cexcel.html' title='在C#中讀取Excel的試算表名稱'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-3576121058928933032</id><published>2010-12-27T14:17:00.010+08:00</published><updated>2011-02-15T15:17:35.336+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="SQL"/><title type='text'>在C#中使用SQLite資料庫</title><content type='html'>自己開發程式的時候，想用資料庫又不希望花一大筆錢&lt;br /&gt;常常會使用SQLite，一個輕量級的嵌入式資料庫系統(僅單一檔案)&lt;br /&gt;由於.net原生並不支援SQLite&lt;br /&gt;可以去&lt;a href=&quot;http://sqlite.phxsoftware.com/&quot;&gt;System.Data.SQLite&lt;/a&gt;找到在公開的函式庫&lt;br /&gt;注意如果是x64的程式，則需要使用x64版本的函式庫，無法混用&lt;br /&gt;&lt;br /&gt;在每次使用資料庫的時候，都需要建立與相關資料庫的連結&lt;br /&gt;&lt;code&gt;&lt;br /&gt;private SQLiteConnection ConnectDatabase()&lt;br /&gt;{&lt;br /&gt;    string path = &quot;Test.db&quot;;&lt;br /&gt;    string password = &quot;Password&quot;;&lt;br /&gt;    SQLiteConnection connection;&lt;br /&gt;&lt;br /&gt;    if (!File.Exists(_databasePath))&lt;br /&gt;    {&lt;br /&gt;        &lt;n1&gt;/// for non-exist database, create it&lt;/n1&gt;&lt;br /&gt;        SQLiteConnection.CreateFile(path);&lt;br /&gt;        connection = new SQLiteConnection(&lt;br /&gt;            &quot;Data Source = &quot; + path);&lt;br /&gt;        connection.Open();&lt;br /&gt;        &lt;n2&gt;connection.ChangePassword(password);&lt;/n2&gt;&lt;br /&gt;    }&lt;br /&gt;    else&lt;br /&gt;    {&lt;br /&gt;        &lt;n1&gt;/// for exist database, connect it&lt;/n1&gt;&lt;br /&gt;        connection = new SQLiteConnection(&lt;br /&gt;            &quot;Data Source = &quot; + path);&lt;br /&gt;        &lt;n2&gt;connection.SetPassword(password);&lt;/n2&gt;&lt;br /&gt;        connection.Open();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return connection;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;這邊要注意的是，由於SQLite本身並沒有支援資料庫加密&lt;br /&gt;有關Password的功能(&lt;n2&gt;紅字部分&lt;/n2&gt;)是System.Data.SQLite實做的&lt;br /&gt;所以製作出來的加密資料庫並不能被其他的SQLite應用讀取&lt;br /&gt;(例如Firefox的附加元件&lt;a href=&quot;https://addons.mozilla.org/zh-TW/firefox/addon/5817/&quot;&gt;SQLite Manager&lt;/a&gt;)&lt;br /&gt;所以如果不打算加密，建議將&lt;n2&gt;紅字部分&lt;/n2&gt;拿掉&lt;br /&gt;&lt;br /&gt;在連結之後，就可以透過該連結，執行SQL的命令&lt;br /&gt;&lt;code&gt;&lt;br /&gt;private void RunCommand(&lt;br /&gt;    SQLiteConnection connection, string commandText)&lt;br /&gt;{&lt;br /&gt;    SQLiteCommand command =&lt;br /&gt;        new SQLiteCommand(connection);&lt;br /&gt;    command.CommandText = commandText;&lt;br /&gt;    command.ExecuteNonQuery();        &lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;除了不需要回傳值的命令(例如CREATE TABLE)以外&lt;br /&gt;SQL最重要的當然是Query的指令&lt;br /&gt;&lt;code&gt;&lt;br /&gt;private List&lt;string&gt; RunQueryCommand(&lt;br /&gt;    SQLiteConnection connection, string commandText)&lt;br /&gt;{&lt;br /&gt;    List&amp;lt;string&amp;gt; result = new List&amp;lt;string&amp;gt;();&lt;br /&gt;&lt;br /&gt;    SQLiteCommand command =&lt;br /&gt;        new SQLiteCommand(connection);&lt;br /&gt;    command.CommandText = commandText;&lt;br /&gt;&lt;br /&gt;    using (SQLiteDataReader queryResult =&lt;br /&gt;        command.ExecuteReader())&lt;br /&gt;    {&lt;br /&gt;        &lt;n1&gt;/// read one row one time&lt;/n1&gt;&lt;br /&gt;        while (queryResult.Read())&lt;br /&gt;        {&lt;br /&gt;            &lt;n1&gt;/// change index to get different column&lt;/n1&gt;&lt;br /&gt;            result.Add(queryResult.GetValue(&lt;n2&gt;0&lt;/n2&gt;)&lt;br /&gt;                .ToString());&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return result;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;當然，在使用完畢後一定要記得將連結中止，否則資料庫檔案會被鎖住&lt;br /&gt;&lt;code&gt;&lt;br /&gt;private void DisconnectDatabase(&lt;br /&gt;    SQLiteConnection connection)&lt;br /&gt;{&lt;br /&gt;    connection.Close();&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;另外，讀取資料庫的時候，如果不能肯定資料表是否存在&lt;br /&gt;則需要先做一個檢查，否則會跳出例外狀況&lt;br /&gt;(當然也是可以直接用try catch將Command包住，端看習慣)&lt;br /&gt;&lt;code&gt;&lt;br /&gt;private bool IsTableExist(&lt;br /&gt;    SQLiteConnection connection, string name)&lt;br /&gt;{&lt;br /&gt;    return connection.GetSchema(&quot;Tables&quot;)&lt;br /&gt;        .Select(&quot;Table_Name = &#39;&quot; + name + &quot;&#39;&quot;)&lt;br /&gt;        .Length &gt; 0;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://support.oss.org.tw/?q=node/157&quot;&gt;SQLite 簡介&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://sqlite.phxsoftware.com/&quot;&gt;System.Data.SQLite&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://catonchuang.blogspot.com/2009/08/sqlite-with-c-shape.html&quot;&gt;C sharp or .Net 使用sqlite 設定&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://addons.mozilla.org/zh-TW/firefox/addon/5817/&quot;&gt;SQLite Manager&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://www.1keydata.com/tw/sql/sql.html&quot;&gt;SQL語法教學&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://sqlite.phxsoftware.com/forums/p/776/8616.aspx&quot;&gt;Check if table exists&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/3576121058928933032/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/12/csqlite.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/3576121058928933032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/3576121058928933032'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/12/csqlite.html' title='在C#中使用SQLite資料庫'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-8832767119143498722</id><published>2010-12-27T13:34:00.003+08:00</published><updated>2010-12-27T13:58:32.011+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>Windows的顯示/隱藏桌面</title><content type='html'>在Windows XP預設的快速啟動列中會有一個捷徑，可以顯示/隱藏桌面&lt;br /&gt;(隱藏/顯示所有已經開啟的視窗)&lt;br /&gt;在XP的時候有時候會不小心砍掉(Win7中已經被放在視窗的右下角，反正也移除不掉，就不會有這個困擾)，這時候可以自己重新做一個捷徑&lt;br /&gt;&lt;br /&gt;先開一個純文字檔，內容如下&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[Shell]&lt;br /&gt;Command=2&lt;br /&gt;IconFile=explorer.exe,3&lt;br /&gt;[Taskbar]&lt;br /&gt;Command=ToggleDesktop&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;並將檔案附檔名改為.scf(檔名倒是無所謂，一般習慣設成&quot;ShowDesktop.scf&quot;或&quot;顯示桌面.scf&quot;)就可以了&lt;br /&gt;&lt;br /&gt;如果想要在程式中做出同樣的功能，則可以呼叫Shell.Application去呼叫ToggleDesktop這個命令&lt;br /&gt;&lt;code&gt;&lt;br /&gt;void ShowDesktop()&lt;br /&gt;{&lt;br /&gt;    Type shell =&lt;br /&gt;        Type.GetTypeFromProgID(&quot;Shell.Application&quot;);&lt;br /&gt;    shell.InvokeMember(&quot;ToggleDesktop&quot;,&lt;br /&gt;        BindingFlags.InvokeMethod, null,&lt;br /&gt;        Activator.CreateInstance(shell), null);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://support.microsoft.com/kb/190355/EN-US/&quot;&gt;How to re-create the Show desktop icon on the Quick Launch toolbar in Windows XP&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://www.zu14.cn/2009/03/19/csharp-shell-system-swith-to-desktop/&quot;&gt;C#使用系統的「顯示桌面」功能(Shell.Application)&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/8832767119143498722/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/12/windows.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/8832767119143498722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/8832767119143498722'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/12/windows.html' title='Windows的顯示/隱藏桌面'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-2300496098614592716</id><published>2010-12-21T14:15:00.003+08:00</published><updated>2010-12-21T16:20:52.221+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><title type='text'>在WPF中發出鍵盤事件</title><content type='html'>WPF沒有控制鍵盤的API&lt;br /&gt;所以要發出鍵盤事件(例如按下&quot;J&quot;)就必須要呼叫Win32的API了&lt;br /&gt;&lt;code&gt;&lt;br /&gt;private enum KeyEventFlag&lt;br /&gt;{&lt;br /&gt;    KEYEVENTF_KEYDOWN = 0x0000,&lt;br /&gt;    KEYEVENTF_EXTENDEDKEY = 0x0001,&lt;br /&gt;    KEYEVENTF_KEYUP = 0x0002,&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[DllImport(&quot;user32.dll&quot;, SetLastError = true)]&lt;br /&gt;private static extern void keybd_event(&lt;br /&gt;    byte bVk, byte bScan, KeyEventFlag dwFlags,&lt;br /&gt;    IntPtr dwExtraInfo);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;這時發生一個問題，bVk是以Win32中定義的&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd375731%28v=vs.85%29.aspx&quot;&gt;Virtual-Key Codes&lt;/a&gt;做為對照&lt;br /&gt;但是在WPF中所採用的是&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.input.key%28v=VS.90%29.aspx&quot;&gt;Key 列舉型別&lt;/a&gt;&lt;br /&gt;需要使用KeyInterop做轉換，所以實際上發出按下鍵盤的函式如下&lt;br /&gt;&lt;code&gt;&lt;br /&gt;private void SendKeyDown(Key key)&lt;br /&gt;{&lt;br /&gt;    keybd_event(&lt;br /&gt;        (byte)KeyInterop.VirtualKeyFromKey(key), 0,&lt;br /&gt;        KeyEventFlag.KEYEVENTF_KEYDOWN, IntPtr.Zero);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;另外，如果要送出放開鍵盤的事件，那就把KEYEVENTF_KEYDOWN換成KEYEVENTF_KEYUP，而連續送出一個按下加上一個放開，就變成Click了&lt;br /&gt;同理，要發出復合鍵則是再放開前按下所有鍵，再放開即可&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://efreedom.com/Question/1-1153009/Can-Convert-SystemWindowsInputKey-SystemWindowsFormsKeys&quot;&gt;.NET - How can I convert &#39;System.Windows.Input.Key&#39; to &#39;System.Windows.Forms.Keys&#39;?&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/2300496098614592716/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/12/wpf.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/2300496098614592716'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/2300496098614592716'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/12/wpf.html' title='在WPF中發出鍵盤事件'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-6142274174628393426</id><published>2010-09-03T18:47:00.004+08:00</published><updated>2010-09-03T19:01:04.921+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>在C#中確認視窗是否是全螢幕</title><content type='html'>要確認一個視窗是否是全螢幕&lt;br /&gt;可以直接比對視窗的大小是否與螢幕大小相同&lt;br /&gt;因為如果不是全螢幕的視窗，那至少會有一部分被工具列佔走&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public struct RECT&lt;br /&gt;{&lt;br /&gt;    public int left;&lt;br /&gt;    public int top;&lt;br /&gt;    public int right;&lt;br /&gt;    public int bottom;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[DllImport(&quot;user32.dll&quot;)]&lt;br /&gt;private static extern int GetWindowRect(&lt;br /&gt;    IntPtr hWnd, out RECT lpRect);&lt;br /&gt;&lt;br /&gt;bool IsFullScreen(IntPtr h)&lt;br /&gt;{&lt;br /&gt;    &lt;n1&gt;/// get window bound from handle&lt;/n1&gt;&lt;br /&gt;    RECT b;&lt;br /&gt;    GetWindowRect(h, out b);&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// get screen bound from handle&lt;/n1&gt;&lt;br /&gt;    Rectangle r = Screen.FromHandle(h).Bounds;&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// check if the two size is the same&lt;/n1&gt;&lt;br /&gt;    if ((b.bottom - b.top) == r.Height &amp;&amp;&lt;br /&gt;        (b.right - b.left) == r.Width)&lt;br /&gt;    {&lt;br /&gt;        return true;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return false;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;注意Screen這個類別是宣告在System.Windows.Forms裡面&lt;br /&gt;還有Rectangle是宣告在System.Drawing裡面&lt;br /&gt;所以如果是WPF的程式，則需要另外新增參考&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms633519%28VS.85%29.aspx&quot;&gt;GetWindowRect Function&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd162897%28v=VS.85%29.aspx&quot;&gt;RECT Structure&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-cn/library/system.windows.forms.screen.fromhandle.aspx&quot;&gt;Screen.FromHandle 方法&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://www.eggheadcafe.com/community/aspnet/2/10171926/detect-whether-active-window-is-full-screen.aspx&quot;&gt;Detect whether active window is full screen&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/6142274174628393426/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/09/c.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/6142274174628393426'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/6142274174628393426'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/09/c.html' title='在C#中確認視窗是否是全螢幕'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-5980523679655235567</id><published>2010-09-03T09:54:00.006+08:00</published><updated>2010-09-03T18:40:43.790+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>在C#中取得前景視窗(ForegroundWindow)的應用程式名稱</title><content type='html'>如果在寫工具類的程式，有時會需要知道目前前景的視窗&lt;br /&gt;(Foreground，也就是持有Focus的視窗)&lt;br /&gt;這時候可以透過Win32的API來取得相關的資訊&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[DllImport(&quot;user32.dll&quot;)]&lt;br /&gt;static extern IntPtr GetForegroundWindow();&lt;br /&gt;&lt;br /&gt;[DllImport(&quot;user32.dll&quot;)]&lt;br /&gt;public static extern int GetWindowThreadProcessId(&lt;br /&gt;    IntPtr hWnd, out int lpdwProcessId);&lt;br /&gt;&lt;br /&gt;string GetForegroundApplicationName()&lt;br /&gt;{&lt;br /&gt;    &lt;n1&gt;/// get foreground window handle&lt;/n1&gt;&lt;br /&gt;    IntPtr h = GetForegroundWindow();&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// get foreground process from handle&lt;/n1&gt;&lt;br /&gt;    int pId;&lt;br /&gt;    GetWindowThreadProcessId(h, out pId);&lt;br /&gt;    Process p = Process.GetProcessById(pId);&lt;br /&gt;&lt;br /&gt;    return p.ProcessName;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms633505%28VS.85%29.aspx&quot;&gt;GetForegroundWindow Function&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms633522%28VS.85%29.aspx&quot;&gt;GetWindowThreadProcessId Function&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/76fkb36k%28v=VS.80%29.aspx&quot;&gt;Process.GetProcessById 方法 (Int32)&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/5980523679655235567/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/09/cforegroundwindow.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/5980523679655235567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/5980523679655235567'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/09/cforegroundwindow.html' title='在C#中取得前景視窗(ForegroundWindow)的應用程式名稱'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-2261918198687024895</id><published>2010-07-16T10:04:00.003+08:00</published><updated>2010-07-16T10:34:58.580+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>查找註冊表的變動(WinDiff)</title><content type='html'>在寫Windows程式時，如果遇到比較冷門的功能&lt;br /&gt;常常會遇到怎麼找都找不到API的狀況(甚至上msdn也沒人回應)&lt;br /&gt;如果這時候你發現其實有手動的方式可以達到同樣的目的&lt;br /&gt;(例如之前提過的&lt;a href=&quot;http://codingjames.blogspot.com/2010/02/dpi-virtualization.html&quot;&gt;DPI Virtualization&lt;/a&gt;)&lt;br /&gt;那就可以考慮一下去比對註冊表的變動了&lt;br /&gt;&lt;br /&gt;在Windows系統中幾乎所有的變動都會改變註冊表&lt;br /&gt;在執行列打入regedit就可以看到一堆機碼&lt;br /&gt;基本上真的無從找起&lt;br /&gt;&lt;br /&gt;這時候就要用到WinDiff工具了&lt;br /&gt;可以參考&lt;a href=&quot;http://support.microsoft.com/kb/159214&quot;&gt;如何使用 Windiff.exe 公用程式&lt;/a&gt;&lt;br /&gt;這個工具可以讓你比對兩個文字檔案，找到並瀏覽差異&lt;br /&gt;&lt;br /&gt;1. 在做想要達到目的的操作前，先將註冊表匯出成文字檔&lt;br /&gt;2. 做手動的操作&lt;br /&gt;3. 重開註冊表，並匯出成另一個文字檔&lt;br /&gt;4. 開啟WinDiff，從表單中選取File-&gt;CompareFiles...&lt;br /&gt;   並分別選取兩個文字檔&lt;br /&gt;5. 如果兩個檔案相同，會顯示identical的訊息&lt;br /&gt;6. 如果不同，會顯示紅字，雙擊紅字就會展開整份檔案&lt;br /&gt;7. 首先會到第一筆差異處，利用下一筆(F8)或上一筆(F7)瀏覽&lt;br /&gt;&lt;br /&gt;接下來就是用眼睛比對了&lt;br /&gt;通常你會發現一些關鍵字出現，就是你要找的了&lt;br /&gt;這裡有幾點需要注意的&lt;br /&gt;1. 整份註冊表還蠻大的(100MB+是正常的)&lt;br /&gt;   可以考慮針對有關的註冊表查找，或是分成很多個表匯出&lt;br /&gt;   這樣可以節省比對的時間&lt;br /&gt;2. 使用WinDiff比對完一對檔案後，最好是重開後再比對下一份&lt;br /&gt;   因為似乎還是會占用記憶體，所以會變慢很多&lt;br /&gt;3. 一個動作可能會更動到註冊表的很多地方&lt;br /&gt;   就算已經找到，還是建議繼續搜索完其他的部分&lt;br /&gt;&lt;br /&gt;在找到差異後，就可以透過編輯註冊表的API來做同樣的調整了&lt;br /&gt;例如&lt;a href=&quot;http://codingjames.blogspot.com/2010/02/dpi-virtualization.html&quot;&gt;DPI Virtualization&lt;/a&gt;中的方法&lt;br /&gt;不過這邊要強調，這種做法其實有一定的風險&lt;br /&gt;(當然，如果只是檢查倒是無所謂，但是有修改就很難說了)&lt;br /&gt;你有可能有漏掉沒有改到的地方(造成註冊表的關聯錯誤)&lt;br /&gt;建議是先在測試的機器(可隨時重新安裝的電腦)上，手動做幾次&lt;br /&gt;如果確定穩定而且達到目的的話再用程式去改&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://support.microsoft.com/kb/159214&quot;&gt;如何使用 Windiff.exe 公用程式&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/2261918198687024895/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/07/windiff.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/2261918198687024895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/2261918198687024895'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/07/windiff.html' title='查找註冊表的變動(WinDiff)'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-89326945815739747</id><published>2010-06-24T13:04:00.007+08:00</published><updated>2010-06-24T13:29:43.488+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>在C#中啟動服務(Service)</title><content type='html'>在Windows系統裡面有非常多的服務&lt;br /&gt;但是有些時後服務並不會自動開啟&lt;br /&gt;例如快速插拔硬體後，有些相關的服務會沒有被啟動(例如手寫板)&lt;br /&gt;所以這時候就需要另外啟動這些服務了&lt;br /&gt;&lt;br /&gt;如果要手動啟動這些服務，可以到&lt;br /&gt;控制台-&gt;系統管理工具-&gt;服務&lt;br /&gt;找到相關的服務並按滑鼠右鍵啟動&lt;br /&gt;&lt;br /&gt;但是有時候在程式進行中一樣會發現服務沒被啟動&lt;br /&gt;就需要用ServiceController去操作服務的狀態了&lt;br /&gt;&lt;code&gt;&lt;br /&gt;private void StartService(string s)&lt;br /&gt;{&lt;br /&gt;    try&lt;br /&gt;    {&lt;br /&gt;        ServiceController sc = new ServiceController(s);&lt;br /&gt;&lt;br /&gt;        &lt;n1&gt;/// if service is stopped, start it&lt;/n1&gt;&lt;br /&gt;        if (sc.Status ==&lt;br /&gt;            ServiceControllerStatus.Stopped)&lt;br /&gt;        {&lt;br /&gt;            &lt;n1&gt;/// start the service&lt;/n1&gt;&lt;br /&gt;            sc.Start();&lt;br /&gt;            sc.WaitForStatus(&lt;br /&gt;                ServiceControllerStatus.Running);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    catch (Exception e)&lt;br /&gt;    {&lt;br /&gt;        Console.WriteLine(&lt;br /&gt;            &quot;Exception : &quot;, e.Message);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;因為服務名稱可能傳入錯誤，或是在該裝置上沒有該服務&lt;br /&gt;(例如一般XP上面沒有觸控筆的服務)&lt;br /&gt;所以在使用的時候建議使用try-catch&lt;br /&gt;&lt;br /&gt;傳入的參數就是服務的名稱，例如觸控筆的服務&lt;br /&gt;&lt;code&gt;&lt;br /&gt;StartService(&lt;n2&gt;&quot;TabletInputService&quot;&lt;/n2&gt;);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/7fs05y7h%28v=VS.80%29.aspx&quot;&gt;ServiceController 類別&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms686321%28v=VS.85%29.aspx&quot;&gt;StartService Function&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/89326945815739747/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/06/cservice.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/89326945815739747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/89326945815739747'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/06/cservice.html' title='在C#中啟動服務(Service)'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-5558334724684384195</id><published>2010-05-28T10:16:00.005+08:00</published><updated>2010-05-28T10:53:56.699+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>在C#中啟用及關閉多點觸控</title><content type='html'>在.net 4還沒有完全成熟之前，要開發win7的多點觸控程式&lt;br /&gt;可以透過Windows 7 Multitouch .NET Interop Sample Library&lt;br /&gt;請參考&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/windows/ee517433.aspx&quot;&gt;建立多點觸控應用程式&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;但是有時候並不希望另外使用其他的函式庫&lt;br /&gt;這時候可以透過簡單的Win32 API達到同樣的效果&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[DllImport(&quot;User32.dll&quot;, SetLastError = true)]&lt;br /&gt;public static extern bool SetProp(&lt;br /&gt;    IntPtr hWnd, string lpString, IntPtr hData);&lt;br /&gt;&lt;br /&gt;[DllImport(&quot;User32.dll&quot;, SetLastError = true)]&lt;br /&gt;public static extern IntPtr GetProp(&lt;br /&gt;    IntPtr hWnd, string lpString);&lt;br /&gt;&lt;br /&gt;const int TABLET_ENABLE_MULTITOUCHDATA = 0x01000000;&lt;br /&gt;const string TPS = &quot;MicrosoftTabletPenServiceProperty&quot;;&lt;br /&gt;&lt;br /&gt;bool EnableMultiStylus()&lt;br /&gt;{&lt;br /&gt;    &lt;n1&gt;/// get current window handle&lt;/n1&gt;&lt;br /&gt;    Window w = Application.Current.MainWindow;&lt;br /&gt;    IntPtr h = new WindowInteropHelper(w).Handle;&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// get current tablet property&lt;/n1&gt;&lt;br /&gt;    IntPtr tp = GetProp(h, TPS);&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// set with enabled multi-touch flag&lt;/n1&gt;&lt;br /&gt;    return SetProp(h, TPS,&lt;br /&gt;        new IntPtr(tp.ToInt32() |&lt;br /&gt;            TABLET_ENABLE_MULTITOUCHDATA));&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;在這之後就可以直接使用stylus的事件來接收多個觸控點的事件&lt;br /&gt;不過這時候如果註冊了滑鼠事件，就會發現滑鼠事件也被影響了&lt;br /&gt;第二點下去及動作同時也會觸發滑鼠事件，進而造成困擾&lt;br /&gt;(因為滑鼠事件沒辦法判斷哪個事件是由哪個點引發的)&lt;br /&gt;所以記得在不需要使用的時候把多點觸控事件給關掉&lt;br /&gt;&lt;code&gt;&lt;br /&gt;bool DisableMultiStylus()&lt;br /&gt;{&lt;br /&gt;    &lt;n1&gt;/// get current window handle&lt;/n1&gt;&lt;br /&gt;    Window w = Application.Current.MainWindow;&lt;br /&gt;    IntPtr h = new WindowInteropHelper(w).Handle;&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// get current tablet property&lt;/n1&gt;&lt;br /&gt;    IntPtr tp = GetProp(h, TPS);&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// set with disabled multi-touch flag&lt;/n1&gt;&lt;br /&gt;    return SetProp(h, TPS,&lt;br /&gt;        new IntPtr(tp.ToInt32() &amp;&lt;br /&gt;            ~TABLET_ENABLE_MULTITOUCHDATA));&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/windows/ee517433.aspx&quot;&gt;建立多點觸控應用程式&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms633568%28VS.85%29.aspx&quot;&gt;SetProp Function&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms633564%28v=VS.85%29.aspx&quot;&gt;GetProp Function&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd372996%28VS.85%29.aspx&quot;&gt;IRealTimeStylus3::MultiTouchEnabled Property&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/5558334724684384195/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/05/c_28.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/5558334724684384195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/5558334724684384195'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/05/c_28.html' title='在C#中啟用及關閉多點觸控'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-4945070424561658454</id><published>2010-05-27T13:36:00.002+08:00</published><updated>2010-05-28T10:00:14.444+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>在C#中做字串分析</title><content type='html'>C#中的字串本身就有一些簡單的分析，例如Contains或EndsWith&lt;br /&gt;但是如果是比較複雜的判斷，例如是否全部由字母構成&lt;br /&gt;就需要使用正規表式(Regular Expression)來判斷了&lt;br /&gt;&lt;code&gt;&lt;br /&gt;bool IsAlpha(string s)&lt;br /&gt;{&lt;br /&gt;    return !Regex.IsMatch(s, &quot;[^a-zA-Z]&quot;);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;用正規表式來確認字串規則時，會在字串中進行搜索&lt;br /&gt;所以如果要判斷一個字串是否滿足&quot;全部都由字母構成&quot;&lt;br /&gt;實際上得去判斷是否沒有&quot;其餘字符存在&quot;&lt;br /&gt;&lt;br /&gt;另外，正規表式也可以做成執行個體&lt;br /&gt;&lt;code&gt;&lt;br /&gt;bool IsAlpha(string s)&lt;br /&gt;{&lt;br /&gt;    Regex r = new Regex(&quot;[^a-zA-Z]&quot;);&lt;br /&gt;&lt;br /&gt;    return !r.IsMatch(s);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;注意這裏的執行個體中的規則是不可變的&lt;br /&gt;所以如果有大量的運算都需要用到同樣的規則再這樣使用&lt;br /&gt;否則用靜態的方式會比較有彈性&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://www.c-sharpcorner.com/UploadFile/prasad_1/RegExpPSD12062005021717AM/RegExpPSD.aspx&quot;&gt;Regular Expressions Usage in C# &lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://zh.wikipedia.org/zh-tw/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F&quot;&gt;正規表式&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/6f7hht7k%28v=VS.95%29.aspx&quot;&gt;Regex 類別&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.text.regularexpressions.regex.ismatch%28v=VS.95%29.aspx&quot;&gt;Regex.IsMatch 方法&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/4945070424561658454/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/05/c_27.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/4945070424561658454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/4945070424561658454'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/05/c_27.html' title='在C#中做字串分析'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-6759237141835905392</id><published>2010-05-25T16:05:00.007+08:00</published><updated>2010-05-25T19:08:35.534+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><category scheme="http://www.blogger.com/atom/ns#" term="XAML"/><title type='text'>將WPF介面多國語言化(Localization)</title><content type='html'>要將WPF介面變成支援多國語言首先要注意一個問題&lt;br /&gt;因為介面可能同時定義在XAML或C#檔案中&lt;br /&gt;所以如果使用傳統的resx或是單純讀文字檔的方法是沒辦法直接做到的&lt;br /&gt;(當然，如果把所有的介面文字都使用C#定義也是可行&lt;br /&gt;不過這樣就不太符合WPF的精神了)&lt;br /&gt;&lt;br /&gt;這時候需要加入新的資源字典(ResourceDictionary)&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHscalrrcYaxEdhlAq-VBKOHO_kVoa_Qg1l_QeqaROIdPkeaCWlyVzh721icRGkJlWNzWbRXNQg6Yrw5ntgJqsoY3JazZ9o1acif0u6Rl2C1IMhGBJ0NNwYqdm2U5zCwssdKhCWw6PzYsL/s1600/add+new+dictionary.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHscalrrcYaxEdhlAq-VBKOHO_kVoa_Qg1l_QeqaROIdPkeaCWlyVzh721icRGkJlWNzWbRXNQg6Yrw5ntgJqsoY3JazZ9o1acif0u6Rl2C1IMhGBJ0NNwYqdm2U5zCwssdKhCWw6PzYsL/s1600/add+new+dictionary.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5475153189742983650&quot; /&gt;&lt;/a&gt;&lt;br /&gt;資源字典是一個XAML檔案，通常的命名會以CultureInfo的Name命名&lt;br /&gt;(例如en-US.xaml或zh-TW.xaml)&lt;br /&gt;這邊我們定義了一系列的字串，並賦予對應的索引(key)&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;ResourceDictionary&lt;br /&gt; ...&lt;br /&gt;    xmlns:sys=&quot;clr-namespace:System;assembly=mscorlib&quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;sys:String x:Key=&quot;OK&quot;&amp;gt;&lt;br /&gt;        OK&lt;br /&gt;    &amp;lt;/sys:String&amp;gt;&lt;br /&gt;    &amp;lt;sys:String x:Key=&quot;Msg&quot;&amp;gt;&lt;br /&gt;        Msg&lt;br /&gt;    &amp;lt;/sys:String&amp;gt;&lt;br /&gt;&amp;lt;/ResourceDictionary&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;繁體中文的語系檔如下&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;ResourceDictionary&lt;br /&gt; ...&lt;br /&gt;    xmlns:sys=&quot;clr-namespace:System;assembly=mscorlib&quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;sys:String x:Key=&quot;OK&quot;&amp;gt;&lt;br /&gt;        確定&lt;br /&gt;    &amp;lt;/sys:String&amp;gt;&lt;br /&gt;    &amp;lt;sys:String x:Key=&quot;Msg&quot;&amp;gt;&lt;br /&gt;        訊息&lt;br /&gt;    &amp;lt;/sys:String&amp;gt;&lt;br /&gt;&amp;lt;/ResourceDictionary&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;必須注意的是，此時此資源字典的BuildAction可以設定為Page或Content&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHoXFnzJz2aDJp9fhbNvaHTwRyTQErGqHM7y-VjUQdkwFs5zbOJuyIB-iuNgqj0O9mj7-zUJtLRI_Mhreo3_5I_u7RjXHdG743-HHMGNiNeGugHjwUqpNfJjIuPCzJwH6po4VLvHa-vOLq/s1600/build+action+page.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 300px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHoXFnzJz2aDJp9fhbNvaHTwRyTQErGqHM7y-VjUQdkwFs5zbOJuyIB-iuNgqj0O9mj7-zUJtLRI_Mhreo3_5I_u7RjXHdG743-HHMGNiNeGugHjwUqpNfJjIuPCzJwH6po4VLvHa-vOLq/s1600/build+action+page.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5475154866000869890&quot; /&gt;&lt;/a&gt;&lt;br /&gt;設為Page的時候，此檔案會直接被包含到應用程式中&lt;br /&gt;通常在預設語系會採用此種做法(確保至少有一種語言字典可以被找到)&lt;br /&gt;&lt;br /&gt;而設成Content的時候，將會將此檔案獨立出來&lt;br /&gt;此時，複製到輸出目錄(CopyToOutputDirectory)&lt;br /&gt;需設成有更新時才複製(Copy if newer)或永遠複製(Copy always)&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWj0Myz1A7u8corZKrMmm9Yamh2DlhuHd-hdonipoUbs0rw5lDAM_fw6d29ZbgiNWqQNqJU2yMLxqeMYcLq40xp2moYW3S297jfjklZjXMh5H3RLEnuHu_zMULW2O0zRwZkqOLx4s2c_4G/s1600/copy+to.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 300px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWj0Myz1A7u8corZKrMmm9Yamh2DlhuHd-hdonipoUbs0rw5lDAM_fw6d29ZbgiNWqQNqJU2yMLxqeMYcLq40xp2moYW3S297jfjklZjXMh5H3RLEnuHu_zMULW2O0zRwZkqOLx4s2c_4G/s1600/copy+to.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5475161721510854162&quot; /&gt;&lt;/a&gt;&lt;br /&gt;這種方式的好處是可以彈性的加入或移除某種語系的支援而不需要重新編譯&lt;br /&gt;但是就可能會有很多檔案，在發佈的時候會造成一些麻煩&lt;br /&gt;而且使用者可以任意的改動語系檔案，可能造成其他的錯誤&lt;br /&gt;&lt;br /&gt;另外一種就是將非預設語系都包成另一個Dll(全部都設成page)&lt;br /&gt;動態載入需要的語系，這樣一樣可以在不需要重新編譯程式的狀態下換語系檔&lt;br /&gt;也可以保有語系檔的封閉性，只是在讀的時候可能會稍微麻煩一些&lt;br /&gt;可以參考&lt;a href=&quot;http://codingjames.blogspot.com/2009/09/wpf.html&quot;&gt;在WPF中引用被封裝的資源檔(影像)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;在定義資源檔後，可以透過&lt;br /&gt;&lt;code&gt;&lt;br /&gt;private void LoadLanguage()&lt;br /&gt;{&lt;br /&gt;    ResourceDictionary rd = null;&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// get current culture name&lt;/n1&gt;&lt;br /&gt;    string lang = CultureInfo.CurrentCulture.Name;&lt;br /&gt;&lt;br /&gt;    try&lt;br /&gt;    {&lt;br /&gt;        rd = Application.LoadComponent(&lt;br /&gt;            new Uri(lang + &quot; .xaml&quot;, UriKind.Relative))&lt;br /&gt;            as ResourceDictionary;&lt;br /&gt;    }&lt;br /&gt;    catch&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    if (rd != null)&lt;br /&gt;    {&lt;br /&gt;        &lt;n1&gt;/// find current lang xaml, replace default&lt;/n1&gt;&lt;br /&gt;        if (Resources.MergedDictionaries.Count &gt; 0)&lt;br /&gt;        {&lt;br /&gt;            Resources.MergedDictionaries.Clear();&lt;br /&gt;        }&lt;br /&gt;        Resources.MergedDictionaries.Add(rd);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;將語系檔載入到應用程式的資源裡面&lt;br /&gt;&lt;br /&gt;而在使用的地方則可以使用DynamicResource去讀取&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;Button Content=&quot;{DynamicResource OK}&quot;&lt;br /&gt;        Click=&quot;BtnClick&quot; /&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;如果是在C#檔裡則是可以用FindResource去讀&lt;br /&gt;&lt;code&gt;&lt;br /&gt;private void BtnClick(object sender, RoutedEventArgs e)&lt;br /&gt;{&lt;br /&gt;    MessageBox.Show(FindResources(&quot;Msg&quot;) as string);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;此時會從物件本身開始向上查找，直到找到或Application層級為止&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://tech.it168.com/msoft/2007-11-08/200711082236031.shtml&quot;&gt;關於讓WPF軟件界面支持全球化和本地化&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://www.dotblogs.com.tw/bauann/archive/2008/07/02/4419.aspx&quot;&gt;WPF - Resource&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.frameworkelement.findresource.aspx&quot;&gt;FrameworkElement.FindResource 方法&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/ms750613.aspx&quot;&gt;資源概觀&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/6759237141835905392/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/05/wpflocalization.html#comment-form' title='1 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/6759237141835905392'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/6759237141835905392'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/05/wpflocalization.html' title='將WPF介面多國語言化(Localization)'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHscalrrcYaxEdhlAq-VBKOHO_kVoa_Qg1l_QeqaROIdPkeaCWlyVzh721icRGkJlWNzWbRXNQg6Yrw5ntgJqsoY3JazZ9o1acif0u6Rl2C1IMhGBJ0NNwYqdm2U5zCwssdKhCWw6PzYsL/s72-c/add+new+dictionary.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-8429203883975191100</id><published>2010-05-19T17:15:00.004+08:00</published><updated>2010-05-19T18:00:51.012+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><title type='text'>在WPF中觸控事件的捕捉</title><content type='html'>在&lt;a href=&quot;http://codingjames.blogspot.com/2010/05/wpfstylus-event.html&quot;&gt;在WPF中觸控事件(Stylus Event)傳遞&lt;/a&gt;中&lt;br /&gt;我們可以觀察到一般觸控事件的傳遞&lt;br /&gt;但是如果我們在中間的矩形按下，卻移開到視窗之外再釋放&lt;br /&gt;那Up的事件全部都不會發生了，這時候就需要用到捕捉了&lt;br /&gt;&lt;br /&gt;捕捉有兩種，CaptureMouse以及CaptureStylus&lt;br /&gt;經過實際測試，這兩個動作是完全一致的&lt;br /&gt;(也許是為了讓寫觸控AP的RD不要更動太多)&lt;br /&gt;&lt;br /&gt;先在PreviewMouseLeftButtonDown的地方做CaptureMouse&lt;br /&gt;&lt;code&gt;&lt;br /&gt;private void CMouseEH(object sender, RoutedEventArgs e)&lt;br /&gt;{&lt;br /&gt;    (sender as FrameworkElement).CaptureMouse();&lt;br /&gt;    Console.WriteLine(&lt;br /&gt;        (sender as FrameworkElement).Name + &quot; : &quot; + &lt;br /&gt;        e.RoutedEvent.Name);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;記得要在對應的地方(PreviewMouseLeftButtonUp)將滑鼠捕捉釋放掉&lt;br /&gt;&lt;code&gt;&lt;br /&gt;private void RMouseEH(object sender, RoutedEventArgs e)&lt;br /&gt;{&lt;br /&gt;    (sender as FrameworkElement).ReleaseMouseCapture();&lt;br /&gt;    Console.WriteLine(&lt;br /&gt;        (sender as FrameworkElement).Name + &quot; : &quot; + &lt;br /&gt;        e.RoutedEvent.Name);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;為了更清楚的看出捕捉的效果，我們將這兩個事件放在Grd上&lt;br /&gt;得出的結果如下&lt;br /&gt;&lt;output1&gt;&lt;br /&gt;Win : PreviewStylusDown&lt;br /&gt;Grd : PreviewStylusDown&lt;br /&gt;Rec : PreviewStylusDown&lt;br /&gt;Rec : StylusDown&lt;br /&gt;Grd : StylusDown&lt;br /&gt;Win : StylusDown&lt;br /&gt;Win : PreviewMouseLeftButtonDown&lt;br /&gt;Grd : PreviewMouseLeftButtonDown&lt;br /&gt;Rec : PreviewMouseLeftButtonDown&lt;br /&gt;Grd : MouseLeftButtonDown&lt;br /&gt;Win : MouseLeftButtonDown&lt;br /&gt;Win : PreviewStylusUp&lt;br /&gt;Grd : PreviewStylusUp&lt;br /&gt;Grd : StylusUp&lt;br /&gt;Win : StylusUp&lt;br /&gt;Win : PreviewMouseLeftButtonUp&lt;br /&gt;Grd : PreviewMouseLeftButtonUp&lt;br /&gt;Rec : MouseLeftButtonUp&lt;br /&gt;Grd : MouseLeftButtonUp&lt;br /&gt;Win : MouseLeftButtonUp&lt;br /&gt;&lt;/output1&gt;&lt;br /&gt;而如果在PreviewStylus事件中捕捉Stylus的話&lt;br /&gt;結果如下&lt;br /&gt;&lt;output1&gt;&lt;br /&gt;Win : PreviewStylusDown&lt;br /&gt;Grd : PreviewStylusDown&lt;br /&gt;Rec : PreviewStylusDown&lt;br /&gt;Grd : StylusDown&lt;br /&gt;Win : StylusDown&lt;br /&gt;Win : PreviewMouseLeftButtonDown&lt;br /&gt;Grd : PreviewMouseLeftButtonDown&lt;br /&gt;Grd : MouseLeftButtonDown&lt;br /&gt;Win : MouseLeftButtonDown&lt;br /&gt;Win : PreviewStylusUp&lt;br /&gt;Grd : PreviewStylusUp&lt;br /&gt;Rec : StylusUp&lt;br /&gt;Grd : StylusUp&lt;br /&gt;Win : StylusUp&lt;br /&gt;Win : PreviewMouseLeftButtonUp&lt;br /&gt;Grd : PreviewMouseLeftButtonUp&lt;br /&gt;Rec : PreviewMouseLeftButtonUp&lt;br /&gt;Rec : MouseLeftButtonUp&lt;br /&gt;Grd : MouseLeftButtonUp&lt;br /&gt;Win : MouseLeftButtonUp&lt;br /&gt;&lt;/output1&gt;&lt;br /&gt;從上面兩個結果中可以看出&lt;br /&gt;不論是在滑鼠或是觸控事件中捕捉，都會將該事件繼續傳遞下去&lt;br /&gt;但在該事件傳遞結束後到觸發釋放事件傳遞結束前&lt;br /&gt;所有下層的物件都不再收到任何滑鼠或觸控的事件</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/8429203883975191100/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/05/wpf.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/8429203883975191100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/8429203883975191100'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/05/wpf.html' title='在WPF中觸控事件的捕捉'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-5463438663021082884</id><published>2010-05-19T15:35:00.003+08:00</published><updated>2010-05-19T17:05:23.649+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><category scheme="http://www.blogger.com/atom/ns#" term="XAML"/><title type='text'>在WPF中觸控事件(Stylus Event)傳遞</title><content type='html'>在單點觸控發生時，Windows會觸發Stylus及Mouse的事件&lt;br /&gt;參考&lt;a href=&quot;http://codingjames.blogspot.com/2009/09/wpfbutton.html&quot;&gt;在WPF中滑鼠事件(Mouse Event)傳遞&lt;/a&gt;中使用的結構&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;Window ... Name=&quot;Win&quot;&amp;gt;&lt;br /&gt;    &amp;lt;Grid Name=&quot;Grd&quot;&amp;gt;&lt;br /&gt;        &amp;lt;Rectangle Name=&quot;Rec&quot; /&amp;gt;&lt;br /&gt;    &amp;lt;/Grid&amp;gt;&lt;br /&gt;&amp;lt;/Window&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;因為我們這次觀察的重點是Mouse跟Stylus的交互作用&lt;br /&gt;所以觀察的事件如下&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;th&gt;事件&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PreviewMouseLeftButtonDown&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PreviewMouseLeftButtonUp&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;MouseLeftButtonDown&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;MouseLeftButtonUp&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PreviewStylusDown&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PreviewStylusUp&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;StylusDown&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;StylusUp&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;同樣，將觀察的事件都套用到相同的事件處理函式&lt;br /&gt;依照&lt;a href=&quot;http://codingjames.blogspot.com/2009/09/wpfbutton.html&quot;&gt;在WPF中滑鼠事件(Mouse Event)傳遞&lt;/a&gt;所作的設定&lt;br /&gt;出來的結果會是&lt;br /&gt;&lt;output1&gt;&lt;br /&gt;Win : PreviewStylusDown&lt;br /&gt;Grd : PreviewStylusDown&lt;br /&gt;Rec : PreviewStylusDown&lt;br /&gt;Rec : StylusDown&lt;br /&gt;Grd : StylusDown&lt;br /&gt;Win : StylusDown&lt;br /&gt;Win : PreviewMouseLeftButtonDown&lt;br /&gt;Grd : PreviewMouseLeftButtonDown&lt;br /&gt;Rec : PreviewMouseLeftButtonDown&lt;br /&gt;Rec : MouseLeftButtonDown&lt;br /&gt;Grd : MouseLeftButtonDown&lt;br /&gt;Win : MouseLeftButtonDown&lt;br /&gt;Win : PreviewStylusUp&lt;br /&gt;Grd : PreviewStylusUp&lt;br /&gt;Rec : PreviewStylusUp&lt;br /&gt;Rec : StylusUp&lt;br /&gt;Grd : StylusUp&lt;br /&gt;Win : StylusUp&lt;br /&gt;Win : PreviewMouseLeftButtonUp&lt;br /&gt;Grd : PreviewMouseLeftButtonUp&lt;br /&gt;Rec : PreviewMouseLeftButtonUp&lt;br /&gt;Rec : MouseLeftButtonUp&lt;br /&gt;Grd : MouseLeftButtonUp&lt;br /&gt;Win : MouseLeftButtonUp&lt;br /&gt;&lt;/output1&gt;&lt;br /&gt;從這例子中可以看出Stylus的事件會全部發生完才發生Mouse事件&lt;br /&gt;而Stylus事件上下層間的傳遞也如同Mouse事件一般</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/5463438663021082884/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/05/wpfstylus-event.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/5463438663021082884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/5463438663021082884'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/05/wpfstylus-event.html' title='在WPF中觸控事件(Stylus Event)傳遞'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-682183202717727128</id><published>2010-05-14T14:29:00.005+08:00</published><updated>2010-05-17T18:55:11.317+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>在C#中將數值轉字串</title><content type='html'>在C#中要將一個數值表示成字串可以直接使用ToString的方法&lt;br /&gt;不過在不同的地方可能需要不同的表示法&lt;br /&gt;這時候就要使用ToString(String format)&lt;br /&gt;透過format來定義字串的格式&lt;br /&gt;比較常用的如下&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;th width=&quot;20%&quot;&gt;格式&lt;/th&gt;&lt;th&gt;說明&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;0&lt;/td&gt;&lt;td&gt;固定位數數值字串使用，若該位數不存在則填0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;#&lt;/td&gt;&lt;td&gt;非固定位數數值字串使用，若該位數不存在則不會出現&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;E或e&lt;/td&gt;&lt;td&gt;科學記號(指數)表示法&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td align=&quot;center&quot;&gt;X或x&lt;/td&gt;&lt;td&gt;16進位表示法，僅用於整數數值&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;void ToStringSample()&lt;br /&gt;{&lt;br /&gt;    double n1 = 12.12;&lt;br /&gt;    Console.WriteLine(n1.ToString(&quot;000.000&quot;));&lt;br /&gt;    &lt;n1&gt;/// 012.120&lt;/n1&gt;&lt;br /&gt;    Console.WriteLine(n1.ToString(&quot;###.###&quot;));&lt;br /&gt;    &lt;n1&gt;/// 12.12&lt;/n1&gt;&lt;br /&gt;    Console.WriteLine(n1.ToString(&quot;E&quot;));&lt;br /&gt;    &lt;n1&gt;/// 1.212000E+001&lt;/n1&gt;&lt;br /&gt;&lt;br /&gt;    double n2 = 1234.1234;&lt;br /&gt;    Console.WriteLine(n2.ToString(&quot;000.000&quot;));&lt;br /&gt;    &lt;n1&gt;/// 1234.123&lt;/n1&gt;&lt;br /&gt;    Console.WriteLine(n2.ToString(&quot;###.###&quot;));&lt;br /&gt;    &lt;n1&gt;/// 1234.123&lt;/n1&gt;&lt;br /&gt;    Console.WriteLine(n2.ToString(&quot;E&quot;));&lt;br /&gt;    &lt;n1&gt;/// 1.234123E+003&lt;/n1&gt;&lt;br /&gt;&lt;br /&gt;    double n3 = 0.05;&lt;br /&gt;    Console.WriteLine(n3.ToString(&quot;000.000&quot;));&lt;br /&gt;    &lt;n1&gt;/// 000.050&lt;/n1&gt;&lt;br /&gt;    Console.WriteLine(n3.ToString(&quot;###.###&quot;));&lt;br /&gt;    &lt;n1&gt;/// .05&lt;/n1&gt;&lt;br /&gt;    Console.WriteLine(n3.ToString(&quot;E&quot;));&lt;br /&gt;    &lt;n1&gt;/// 5.000000E-002&lt;/n1&gt;&lt;br /&gt;&lt;br /&gt;    int n4 = 123456;&lt;br /&gt;    Console.WriteLine(n4.ToString(&quot;000.000&quot;));&lt;br /&gt;    &lt;n1&gt;/// 123456.000&lt;/n1&gt;&lt;br /&gt;    Console.WriteLine(n4.ToString(&quot;E&quot;));&lt;br /&gt;    &lt;n1&gt;/// 123456&lt;/n1&gt;&lt;br /&gt;    Console.WriteLine(n4.ToString(&quot;###.###&quot;));&lt;br /&gt;    &lt;n1&gt;/// 1.234560E+005&lt;/n1&gt;&lt;br /&gt;    Console.WriteLine(n4.ToString(&quot;X&quot;));&lt;br /&gt;    &lt;n1&gt;/// 1E240&lt;/n1&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;數值的表示法真的很多，真的需要的話可以直接從MSDN裡面找&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/kfsatb94%28v=VS.95%29.aspx&quot;&gt;Double.ToString 方法 (String)&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/dwhawy9k%28v=VS.95%29.aspx&quot;&gt;標準數值格式字串&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/0c899ak8%28v=VS.95%29.aspx&quot;&gt;自訂數值格式字串&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://topic.csdn.net/t/20050914/17/4270545.html&quot;&gt;Double.ToString如何指定小數點後的精度&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/682183202717727128/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/05/c.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/682183202717727128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/682183202717727128'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/05/c.html' title='在C#中將數值轉字串'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-7005871856462606689</id><published>2010-05-14T13:04:00.005+08:00</published><updated>2010-05-14T13:40:17.614+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><category scheme="http://www.blogger.com/atom/ns#" term="XAML"/><title type='text'>在WPF中宣告非公開類別(internal class)</title><content type='html'>在製作動態連結函式庫(DLL)的時候&lt;br /&gt;有時候會用到一些非公開的類別(在內部使用，卻無法被外部的專案參考)&lt;br /&gt;在C#中僅需在宣告的時候將類別修飾詞改為internal即可&lt;br /&gt;(或是不要用修飾詞，預設即為internal)&lt;br /&gt;&lt;code&gt;&lt;br /&gt;internal class Class1&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;但如果使用WPF的時候在DLL裡面使用了&lt;br /&gt;UserControl或是像Window等使用XAML宣告的類別時&lt;br /&gt;預設的partial class會是public的&lt;br /&gt;(此時即使沒有使用修飾詞也會預設為public)&lt;br /&gt;&lt;br /&gt;如果將cs檔的partial class宣告為internal partial class&lt;br /&gt;編譯時會出現錯誤&lt;br /&gt;原因是XAML會在編譯時自動使用修飾詞public&lt;br /&gt;所以兩個部分類別的修飾不同而造成錯誤&lt;br /&gt;此時就要用x:ClassModifier去設定編譯時使用的修飾詞&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;UserControl&lt;br /&gt;    x:Class=&quot;test_wpf.UserControl1&quot;&lt;br /&gt;    &lt;n2&gt;x:ClassModifier=&quot;internal&quot;&lt;/n2&gt;&lt;br /&gt;    ...&amp;gt;&lt;br /&gt;    ...&lt;br /&gt;&amp;lt;/UserControl&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;此時cs檔對應的類別就要改成&lt;br /&gt;&lt;code&gt;&lt;br /&gt;namespace test_wpf&lt;br /&gt;{&lt;br /&gt;    internal partial class UserControl1 : UserControl&lt;br /&gt;    {&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;或是將修飾詞去掉，就會使用XAML設定的修飾辭為預設&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://weblogs.asp.net/okloeten/archive/2007/11/20/5292593.aspx&quot;&gt;WPF&#39;s Use of Partial Classes&#39; Access Modifiers&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/ms754029%28VS.90%29.aspx&quot;&gt;x:ClassModifier 屬性&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/7005871856462606689/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/05/wpfinternal-class.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/7005871856462606689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/7005871856462606689'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/05/wpfinternal-class.html' title='在WPF中宣告非公開類別(internal class)'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-453222257125339743</id><published>2010-04-02T09:07:00.007+08:00</published><updated>2010-04-02T10:57:22.997+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><title type='text'>在WPF中捕捉螢幕畫面(ScreenShot)</title><content type='html'>WPF中沒有直接可以捕捉螢幕畫面的物件或函式&lt;br /&gt;不過可以使用.net Form的方法做到，先加入參考System.Drawing&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Bitmap CaptureScreen()&lt;br /&gt;{&lt;br /&gt;    &lt;n1&gt;/// new a bitmap with screen width and height&lt;/n1&gt;&lt;br /&gt;    Bitmap b = new Bitmap(&lt;br /&gt;        (int)SystemParameters.PrimaryScreenWidth,&lt;br /&gt;        (int)SystemParameters.PrimaryScreenHeight);&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// copy screen through .net form api&lt;/n1&gt;&lt;br /&gt;    using (Graphics g = Graphics.FromImage(b))&lt;br /&gt;    {&lt;br /&gt;        g.CopyFromScreen(0, 0, 0, 0,&lt;br /&gt;            b.Size, CopyPixelOperation.SourceCopy);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return b;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;這時候得到的是Form使用的Bitmap物件&lt;br /&gt;如果要存成圖檔的話就可以直接使用Bitmap物件的Save&lt;br /&gt;&lt;code&gt;&lt;br /&gt;void SaveBitmap(Bitmap b, string f)&lt;br /&gt;{&lt;br /&gt;    b.Save(f);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;或是再把它轉換成WPF使用的BitmapSource&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[DllImport(&quot;gdi32.dll&quot;)]&lt;br /&gt;[return: MarshalAs(UnmanagedType.Bool)]&lt;br /&gt;static extern bool DeleteObject(IntPtr hObject);&lt;br /&gt;&lt;br /&gt;private static BitmapSource ToBitmapSource(Bitmap b)&lt;br /&gt;{&lt;br /&gt;    &lt;n1&gt;/// transform to hbitmap image&lt;/n1&gt;&lt;br /&gt;    IntPtr hb = b.GetHbitmap();&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// convert hbitmap to bitmap source&lt;/n1&gt;&lt;br /&gt;    BitmapSource bs =&lt;br /&gt;        Imaging.CreateBitmapSourceFromHBitmap(&lt;br /&gt;            hb, IntPtr.Zero, Int32Rect.Empty,&lt;br /&gt;            BitmapSizeOptions.FromEmptyOptions());&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// release temp hbitmap image&lt;/n1&gt;&lt;br /&gt;    DeleteObject(hb);&lt;br /&gt;&lt;br /&gt;    return bs;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;不過由於透明背景的視窗會被放在不同層的顯示記憶體中&lt;br /&gt;這也造成了使用上面的捕捉畫面方法會抓不到透明的視窗&lt;br /&gt;如果希望抓到的畫面包括這樣的視窗，那就要直接用Win32的GDI+函式了&lt;br /&gt;&lt;code&gt;&lt;br /&gt;const uint SRCCOPY = 0x00CC0020;&lt;br /&gt;const uint CAPTUREBLT = 0x40000000;&lt;br /&gt;&lt;br /&gt;[DllImport(&quot;user32.dll&quot;)]&lt;br /&gt;static extern IntPtr GetDesktopWindow();&lt;br /&gt;&lt;br /&gt;[DllImport(&quot;user32.dll&quot;)]&lt;br /&gt;static extern IntPtr GetDC(IntPtr hWnd);&lt;br /&gt;&lt;br /&gt;[DllImport(&quot;gdi32.dll&quot;)]&lt;br /&gt;[return: MarshalAs(UnmanagedType.Bool)]&lt;br /&gt;static extern bool BitBlt(IntPtr hdcDest, int nXDest,&lt;br /&gt;    int nYDest, int nWidth, int nHeight, IntPtr hdcSrc,&lt;br /&gt;    int nXSrc, int nYSrc, uint dwRop);&lt;br /&gt;&lt;br /&gt;[DllImport(&quot;user32.dll&quot;)]&lt;br /&gt;static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);&lt;br /&gt;&lt;br /&gt;void CaptureScreen()&lt;br /&gt;{&lt;br /&gt;    &lt;n1&gt;/// new a bitmap with screen width and height&lt;/n1&gt;&lt;br /&gt;    Bitmap b = new Bitmap(&lt;br /&gt;        (int)SystemParameters.PrimaryScreenWidth,&lt;br /&gt;        (int)SystemParameters.PrimaryScreenHeight);&lt;br /&gt;&lt;br /&gt;    &lt;n1&gt;/// copy screen through gdi+ api&lt;/n1&gt;&lt;br /&gt;    using (Graphics g = Graphics.FromImage(b))&lt;br /&gt;    {&lt;br /&gt;        IntPtr hdc = g.GetHdc();&lt;br /&gt;        IntPtr dh = GetDesktopWindow();&lt;br /&gt;        IntPtr dhdc = GetDC(dh);&lt;br /&gt;        BitBlt(hdc, 0, 0,&lt;br /&gt;            (int)SystemParameters.PrimaryScreenWidth,&lt;br /&gt;            (int)SystemParameters.PrimaryScreenHeight,&lt;br /&gt;            dhdc, 0, 0, SRCCOPY | CAPTUREBLT);&lt;br /&gt;&lt;br /&gt;        &lt;n1&gt;/// release and dispose unmanaged resources&lt;/n1&gt;&lt;br /&gt;        ReleaseDC(dh, dhdc);&lt;br /&gt;        g.ReleaseHdc();&lt;br /&gt;        hdc = IntPtr.Zero;&lt;br /&gt;        dh = IntPtr.Zero;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;這樣就可以抓到透明背景的視窗&lt;br /&gt;但是如果仔細看的話會發現在抓圖的時候，滑鼠游標會有一個閃爍&lt;br /&gt;(需要連續一直抓比較明顯，直接抓是看不太出來的)&lt;br /&gt;這是因為透明圖層跟滑鼠游標是在同一層&lt;br /&gt;但是BitBlt的原則是不要抓到滑鼠游標&lt;br /&gt;所以會再抓取透明圖層的時候會先將滑鼠變不見&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/7a28f9e6-73fc-4157-bc40-1366267155c3&quot;&gt;ScreenShot Application in WPF using GD+&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://pinvoke.net/default.aspx/gdi32/BitBlt.html&quot;&gt;BitBlt (gdi32)&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://technet.microsoft.com/en-us/magazine/2009.02.windowsconfidential.aspx?pr=blog&quot;&gt;The Case of the Disappearing Cursor&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/453222257125339743/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/04/wpfscreenshot.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/453222257125339743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/453222257125339743'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/04/wpfscreenshot.html' title='在WPF中捕捉螢幕畫面(ScreenShot)'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-5024397258468692255</id><published>2010-04-01T16:37:00.005+08:00</published><updated>2010-04-02T09:06:37.497+08: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中的形狀(Shape)增加虛線框</title><content type='html'>在Shape中要加上框線很簡單&lt;br /&gt;只要設定框線的顏色和粗細就好&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;Rectangle Stroke=&quot;Black&quot; StrokeThickness=&quot;2&quot; /&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;再設定框線變成虛線&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;Rectangle Stroke=&quot;Black&quot; StrokeThickness=&quot;2&quot;&lt;br /&gt;           &lt;n2&gt;StrokeDashArray=&quot;3 5&quot;&lt;/n2&gt; /&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;這裡需要兩個數字，一個是虛線中的線段長度&lt;br /&gt;另一個是虛線中的空間長度，單位都是框線的粗度&lt;br /&gt;所以上面例子是粗度為2像素，而每6像素就會空白10像素的長方形外框&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.shapes.shape.strokedasharray.aspx&quot;&gt;Shape.StrokeDashArray 屬性&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/5024397258468692255/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/04/wpfshape.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/5024397258468692255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/5024397258468692255'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/04/wpfshape.html' title='在WPF中的形狀(Shape)增加虛線框'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-3915243610076436972</id><published>2010-03-23T14:37:00.006+08:00</published><updated>2010-03-23T16:38:13.747+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>在C#中使用Unmanagement函式(DllImport)</title><content type='html'>要在Management程式(.net程式)中使用舊有的Unmanagement函式，例如User32裡面的API，需要使用DllImport來做轉換，最單純的用法就像在&lt;a href=&quot;http://codingjames.blogspot.com/2010/02/wpf.html&quot;&gt;在WPF中取得螢幕的解析度&lt;/a&gt;中使用的GetSystemMetrics&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[DllImport(&quot;user32.dll&quot;)]&lt;br /&gt;static extern int GetSystemMetrics(int nIndex);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;這裡僅需要知道這個函式寫在哪個dll，以及傳入傳出的參數形態就可以&lt;br /&gt;簡單的形態轉換可以參考&lt;a href=&quot;http://rthumati.wordpress.com/2009/05/15/managed-and-un-managed-code-in-net/&quot;&gt;Managed and Un-Managed Code in .NET&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;在這邊有幾個可以注意的地方&lt;br /&gt;第一個是可以做函式名稱的轉換(為了統一命名規則之類的原因)&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[DllImport(&quot;user32.dll&quot;) EntryPoint=&quot;GetSystemMetrics&quot;)]&lt;br /&gt;static extern int gsm(int nIndex);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;依照這樣的寫法就可以用一個gsm的函式呼叫原本在User32中叫做GetSystemMetrics的函式&lt;br /&gt;&lt;br /&gt;另一個是如果回傳是BOOLEAN的型別，則需要用MarshalAs來轉換，例如&lt;br /&gt;&lt;code&gt;&lt;br /&gt;BOOLEAN BoolFunction();&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;就需要寫成&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[DllImport(&quot;a.dll&quot;)]&lt;br /&gt;[return: MarshalAs(UnmanagedType.U1)]&lt;br /&gt;static bool BoolFunction();&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/ms182206.aspx&quot;&gt;請以 MarshalAs 標記布林 P/Invoke 引數&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/f5xe74x8.aspx&quot;&gt;指定進入點&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://rthumati.wordpress.com/2009/05/15/managed-and-un-managed-code-in-net/&quot;&gt;Managed and Un-Managed Code in .NET&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.runtime.interopservices.unmanagedtype.aspx&quot;&gt;UnmanagedType 列舉型別&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/3915243610076436972/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/03/cunmanagementdllimport.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/3915243610076436972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/3915243610076436972'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/03/cunmanagementdllimport.html' title='在C#中使用Unmanagement函式(DllImport)'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-1343404564003181326</id><published>2010-03-22T17:18:00.002+08:00</published><updated>2010-03-22T18:23:24.158+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="WPF"/><title type='text'>在WPF中使用部分影像筆刷</title><content type='html'>在WPF中使用影像筆刷(ImageBrush)可以很容易的將文字或是圖形使用想要用的圖片填滿，可以參考&lt;a href=&quot;http://codingjames.blogspot.com/2009/11/wpfimagebrush_06.html&quot;&gt;在WPF中使用影像筆刷(ImageBrush)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;不過有時候我們不想要用整張圖填滿，這時候就需要用ViewBox了&lt;br /&gt;直接設定一個Rect去限定圖片中的某個範圍&lt;br /&gt;然後再依照Stretch的屬性去填滿&lt;br /&gt;&lt;code&gt;&lt;br /&gt;private void SetViewBox(ImageBrush ib, Rect r)&lt;br /&gt;{&lt;br /&gt;    ib.ViewboxUnits = BrushMappingMode.Absolute;&lt;br /&gt;    ib.Viewbox = r;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;這裡採用的是絕對座標&lt;br /&gt;也可以使用相對的方法(BrushMappingMode.RelativeToBoundingBox)&lt;br /&gt;那傳入的Rect就要變成相對於整張圖的座標&lt;br /&gt;例如(0,0,0.5,0.5)就是左上角的四分之一張圖&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.windows.media.tilebrush.viewbox.aspx&quot;&gt;TileBrush.Viewbox 屬性&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/1343404564003181326/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/03/wpf.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/1343404564003181326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/1343404564003181326'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/03/wpf.html' title='在WPF中使用部分影像筆刷'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5699012559868503034.post-615588647830639087</id><published>2010-03-22T13:21:00.004+08:00</published><updated>2010-03-22T14:20:36.231+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>在C#中計算角度</title><content type='html'>在一些圖形回饋的程式中(比如比較炫麗的圓形操控程式)&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/AVvXsEhZsUhjiKAr7we8kpfJHC8ifNQ4tur2UyIs56Rpi5P_O5Xcqnt-jU_s_FQSUg9rvMWmQmE14AxeCF_MgWN0hYkUwzFG0K65VPIe_lTEH44XcGnBIjg-3XgzvAeO_levGtdMrj2PH-nUiuV3/s1600-h/atan.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZsUhjiKAr7we8kpfJHC8ifNQ4tur2UyIs56Rpi5P_O5Xcqnt-jU_s_FQSUg9rvMWmQmE14AxeCF_MgWN0hYkUwzFG0K65VPIe_lTEH44XcGnBIjg-3XgzvAeO_levGtdMrj2PH-nUiuV3/s1600/atan.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5451336340510454066&quot; /&gt;&lt;/a&gt;&lt;br /&gt;一般的想法就是先算兩點的向量，然後除成tan&lt;br /&gt;再用Math裡面的atan去反推回角度&lt;br /&gt;需要考慮分母為零或是正負號的問題&lt;br /&gt;&lt;br /&gt;但其實在Math另外有一個atan2的函式可以直接透過兩點的向量算出角度&lt;br /&gt;&lt;code&gt;&lt;br /&gt;private double CalAngle(Point pa, Point pb)&lt;br /&gt;{&lt;br /&gt;    &lt;n1&gt;/// Y alias is reverse from Cartesian plane&lt;/n1&gt;&lt;br /&gt;    return Math.Atan2(pa.Y - pb.Y, pb.X - pa.X);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;記得在笛卡爾座標系跟螢幕上的座標的Y軸是反向的&lt;br /&gt;所以計算要反過來減&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;參考資料&lt;br /&gt;&lt;a href=&quot;http://msdn.microsoft.com/zh-tw/library/system.math.atan2%28VS.95%29.aspx&quot;&gt;Math.Atan2 方法&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codingjames.blogspot.com/feeds/615588647830639087/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://codingjames.blogspot.com/2010/03/c.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/615588647830639087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5699012559868503034/posts/default/615588647830639087'/><link rel='alternate' type='text/html' href='http://codingjames.blogspot.com/2010/03/c.html' title='在C#中計算角度'/><author><name>James Hsiao</name><uri>http://www.blogger.com/profile/03418988060362909933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/-o_620NPhyJU/ThLR2RhLSqI/AAAAAAAABUk/WhVC6BFbtEM/s1600/163608_1512216926664_1271626404_31181292_7974766_n.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZsUhjiKAr7we8kpfJHC8ifNQ4tur2UyIs56Rpi5P_O5Xcqnt-jU_s_FQSUg9rvMWmQmE14AxeCF_MgWN0hYkUwzFG0K65VPIe_lTEH44XcGnBIjg-3XgzvAeO_levGtdMrj2PH-nUiuV3/s72-c/atan.png" height="72" width="72"/><thr:total>0</thr:total></entry></feed>