<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blog.darkthread.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Darkthread</title><link>http://blog.darkthread.net/blogs/</link><description>黑暗執行緒</description><dc:language>en-US</dc:language><generator>CommunityServer 2007.1 (Debug Build: 20917.1142)</generator><item><title>CODE-批次清除SQL資料庫的孤兒使用者</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/03/17/clear-orphan-users.aspx</link><pubDate>Wed, 17 Mar 2010 07:45:00 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6141</guid><dc:creator>Jeffrey</dc:creator><slash:comments>1</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;
&lt;p&gt;要快速把資料庫掛上另一台SQL Server，我最常用的作法是複製mdf檔案過去，再直接Attach上去。不過，後續在新SQL上建立與原SQL相同帳號並設定權限的過程，常會遇到以下錯誤訊息:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font color="#ff8000"&gt;Microsoft SQL-DMO (ODBC SQLState: 42000) 錯誤 15023: 使用者或角色 &amp;#39;%s&amp;#39; 在目前的資料庫中已經存在。&lt;br /&gt;Microsoft SQL-DMO (ODBC SQLState: 42000) Error 15023: User or role &amp;#39;%s&amp;#39; already exists in the current database.&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;問題出在複製mdf時，同名使用者(&lt;a href="http://support.microsoft.com/kb/314546"&gt;MS KB&lt;/a&gt;定義的名詞叫&amp;quot;孤兒使用者&amp;quot;)也一併被帶過來，&lt;a href="http://support.microsoft.com/kb/240872/"&gt;MS KB&lt;/a&gt;建議的做法是用&lt;a href="http://msdn.microsoft.com/zh-tw/library/ms174378.aspx"&gt;sp_change_users_login&lt;/a&gt;重新建立新帳號與孤兒使用者間的對應。(註: sp_change_users_login已被宣告未來要廢除，可改用ALTER USER)&lt;/p&gt;
&lt;p&gt;不過，我個人比較習慣的做法，是將這些孤兒使用者先一律清除，因為並非所有使用者在新SQL都會有對應的登入帳號，砍掉重練較省事。&lt;/p&gt;
&lt;p&gt;以下的T-SQL可以自動列舉出有哪些孤兒使用者，執行清理門戶的任務，供有需要的朋友參考:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p style="PADDING-BOTTOM:5px;BACKGROUND-COLOR:yellow;PADDING-LEFT:5px;PADDING-RIGHT:5px;PADDING-TOP:5px;"&gt;&lt;font color="#ff0000"&gt;【強烈警告】&lt;br /&gt;本程式若使用不當，可能誤殺忠良，導致資料庫問題，請各位自行斟酌風險決定是否使用，行刑前請務必再三確認!&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;div class="BlogCodeBlock"&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;declare&lt;/span&gt; @name &lt;span class="kwrd"&gt;varchar&lt;/span&gt;(32)&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;declare&lt;/span&gt; @stmt nvarchar(1024)&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;declare&lt;/span&gt; cur &lt;span class="kwrd"&gt;cursor&lt;/span&gt; &lt;span class="kwrd"&gt;for&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="rem"&gt;--以sys的建立日為基準，之後才建立者視為非系統內建(SQL 2005)&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;select&lt;/span&gt; name &lt;span class="kwrd"&gt;from&lt;/span&gt; sys.database_principals&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;where&lt;/span&gt; create_date &amp;gt; &lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre&gt;(&lt;span class="kwrd"&gt;select&lt;/span&gt; create_date &lt;span class="kwrd"&gt;from&lt;/span&gt; sys.database_principals&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt; &lt;span class="kwrd"&gt;where&lt;/span&gt; name = &lt;span class="str"&gt;&amp;#39;sys&amp;#39;&lt;/span&gt;)&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;and&lt;/span&gt; type &lt;span class="kwrd"&gt;in&lt;/span&gt; (&lt;span class="str"&gt;&amp;#39;S&amp;#39;&lt;/span&gt;, &lt;span class="str"&gt;&amp;#39;U&amp;#39;&lt;/span&gt;)&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;open&lt;/span&gt; cur&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;fetch&lt;/span&gt; &lt;span class="kwrd"&gt;next&lt;/span&gt; &lt;span class="kwrd"&gt;from&lt;/span&gt; cur &lt;span class="kwrd"&gt;into&lt;/span&gt; @name&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;while&lt;/span&gt; &lt;span class="preproc"&gt;@@fetch_status&lt;/span&gt; = 0&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;set&lt;/span&gt; @stmt = &lt;span class="str"&gt;&amp;#39;DROP USER [&amp;#39;&lt;/span&gt; + @name + &lt;span class="str"&gt;&amp;#39;]&amp;#39;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;print&lt;/span&gt; @stmt&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="rem"&gt;    --**警告**建議先印出待刪清單，人工檢核過一次再執行&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre&gt;    --&lt;span class="kwrd"&gt;EXEC&lt;/span&gt; dbo.sp_executesql @stmt&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;fetch&lt;/span&gt; &lt;span class="kwrd"&gt;next&lt;/span&gt; &lt;span class="kwrd"&gt;from&lt;/span&gt; cur &lt;span class="kwrd"&gt;into&lt;/span&gt; @name    &lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;close&lt;/span&gt; cur&lt;/pre&gt;&lt;/div&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;deallocate&lt;/span&gt; cur&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6141" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/SQL+2005/default.aspx">SQL 2005</category></item><item><title>CODE-將LINQ查詢結果轉成ADO.NET DataTable</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/03/17/6134.aspx</link><pubDate>Wed, 17 Mar 2010 00:11:00 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6134</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;跟同事討論在新專案中開始採用LINQ，但有些古老元件的API只接受DataTable參數，我想到以前想過可以利用Reflection將LINQ查詢結果轉成DataTable，花了點時間，參考網路上的文章，整理成以下範例:&lt;/p&gt;
&lt;div class="BlogCodeBlock"&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Data;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Reflection;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; ConsoleApplication1&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;class&lt;/span&gt; Program&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//REF: http://3.ly/y8rA&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;//註: .NET 3.5有個IEnumerable.CopyToDataTable&amp;lt;T&amp;gt;()，但T只接受DataRow(感覺有點莊孝維)&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;static&lt;/span&gt; DataTable LinqQueryToDataTable&amp;lt;T&amp;gt;(IEnumerable&amp;lt;T&amp;gt; query)&lt;/pre&gt;&lt;pre&gt;        {&lt;/pre&gt;&lt;pre class="alt"&gt;            DataTable tbl = &lt;span class="kwrd"&gt;new&lt;/span&gt; DataTable();&lt;/pre&gt;&lt;pre&gt;            PropertyInfo[] props = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (T item &lt;span class="kwrd"&gt;in&lt;/span&gt; query)&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (props == &lt;span class="kwrd"&gt;null&lt;/span&gt;) &lt;span class="rem"&gt;//尚未初始化&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                {&lt;/pre&gt;&lt;pre class="alt"&gt;                    Type t = item.GetType();&lt;/pre&gt;&lt;pre&gt;                    props = t.GetProperties();&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (PropertyInfo pi &lt;span class="kwrd"&gt;in&lt;/span&gt; props)&lt;/pre&gt;&lt;pre&gt;                    {&lt;/pre&gt;&lt;pre class="alt"&gt;                        Type colType = pi.PropertyType;&lt;/pre&gt;&lt;pre&gt;                        &lt;span class="rem"&gt;//針對Nullable&amp;lt;&amp;gt;特別處理&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                        &lt;span class="kwrd"&gt;if&lt;/span&gt; (colType.IsGenericType&lt;/pre&gt;&lt;pre&gt;                            &amp;amp;&amp;amp; colType.GetGenericTypeDefinition() == &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Nullable&amp;lt;&amp;gt;))&lt;/pre&gt;&lt;pre class="alt"&gt;                            colType = colType.GetGenericArguments()[0];&lt;/pre&gt;&lt;pre&gt;                        &lt;span class="rem"&gt;//建立欄位&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                        tbl.Columns.Add(pi.Name, colType);&lt;/pre&gt;&lt;pre&gt;                    }&lt;/pre&gt;&lt;pre class="alt"&gt;                }&lt;/pre&gt;&lt;pre&gt;                DataRow row = tbl.NewRow();&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (PropertyInfo pi &lt;span class="kwrd"&gt;in&lt;/span&gt; props)&lt;/pre&gt;&lt;pre&gt;                    row[pi.Name] = pi.GetValue(item, &lt;span class="kwrd"&gt;null&lt;/span&gt;) ?? DBNull.Value;&lt;/pre&gt;&lt;pre class="alt"&gt;                tbl.Rows.Add(row);&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; tbl;&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;class&lt;/span&gt; Person&lt;/pre&gt;&lt;pre class="alt"&gt;        {&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Name { get; set; }&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Score { get; set; }&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;public&lt;/span&gt; DateTime RegDate { get; set; }&lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;&lt;pre class="alt"&gt;        {&lt;/pre&gt;&lt;pre&gt;            List&amp;lt;Person&amp;gt; people = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;Person&amp;gt;() {&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;new&lt;/span&gt; Person { Name=&lt;span class="str"&gt;&amp;quot;Jeffrey&amp;quot;&lt;/span&gt;, Score=32767, RegDate = DateTime.Today },&lt;/pre&gt;&lt;pre&gt;                &lt;span class="kwrd"&gt;new&lt;/span&gt; Person { Name=&lt;span class="str"&gt;&amp;quot;Darkthread&amp;quot;&lt;/span&gt;, Score=65535, RegDate = DateTime.Now }&lt;/pre&gt;&lt;pre class="alt"&gt;            };&lt;/pre&gt;&lt;pre&gt;            var q = from p &lt;span class="kwrd"&gt;in&lt;/span&gt; people&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;where&lt;/span&gt; p.Score &amp;gt; 255&lt;/pre&gt;&lt;pre&gt;                    select p;&lt;/pre&gt;&lt;pre class="alt"&gt;            DataTable t = LinqQueryToDataTable(q);&lt;/pre&gt;&lt;pre&gt;            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Row Count={0}&amp;quot;&lt;/span&gt;, t.Rows.Count);&lt;/pre&gt;&lt;pre class="alt"&gt;            DataRow r = t.Rows[0];&lt;/pre&gt;&lt;pre&gt;            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;1st Person Name={0} Score={1} RegDate={2}&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;                r[&lt;span class="str"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;], r[&lt;span class="str"&gt;&amp;quot;Score&amp;quot;&lt;/span&gt;], r[&lt;span class="str"&gt;&amp;quot;RegDate&amp;quot;&lt;/span&gt;]);&lt;/pre&gt;&lt;pre&gt;            Console.Read();&lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6134" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Linq/default.aspx">Linq</category></item><item><title>CODE-自動產生投影片縮圖索引的PowerPoint VBA</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/03/17/ppt-thumbnail-index-vba.aspx</link><pubDate>Tue, 16 Mar 2010 20:16:19 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6132</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;Excel/Word VBA寫過不少，頭一次寫PowerPoint VBA，拿出來分享一下。&lt;/p&gt; &lt;p&gt;同事跟我分享了多年來的收藏--一大堆精美華麗的投影片範例，需要對長官高層做簡報時，找相近的改一改，唬人效果十足。不過一百多個PPT檔案每個都只有一張投影片(因為背景、樣版不同，難以合併)，瀏覽起來頗為麻煩!&lt;/p&gt; &lt;p&gt;為了感謝同事的慷慨分享，我寫了以下VBA作為回報。這段程式，會逐一列出Slides子目錄下的所有PPT檔，對每一張投影片產生縮圖，然後以一張投影片四張縮圖的方式排版，再為縮圖加上超連結以便開啟原投影片檔案，便做成了方便瀏覽檢閱的索引型錄囉!&lt;/p&gt; &lt;div class="BlogCodeBlock"&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;Option&lt;/span&gt; Explicit&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;Sub&lt;/span&gt; BuildIndex()&lt;/pre&gt;&lt;pre&gt;    &lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="rem"&gt;&amp;#39;FileSystemObject物件&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;Dim&lt;/span&gt; FSO &lt;span class="kwrd"&gt;As&lt;/span&gt; Scripting.FileSystemObject&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;Set&lt;/span&gt; FSO = &lt;span class="kwrd"&gt;New&lt;/span&gt; Scripting.FileSystemObject&lt;/pre&gt;&lt;pre&gt;    &lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="rem"&gt;&amp;#39;取得現有路徑及暫存路徑&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;Dim&lt;/span&gt; sCurrentPath &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;, sTempPath &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    sCurrentPath = ActivePresentation.Path&lt;/pre&gt;&lt;pre&gt;    sTempPath = FSO.GetSpecialFolder(TemporaryFolder)&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;/pre&gt;&lt;pre&gt;    &lt;span class="rem"&gt;&amp;#39;索引PPT及標的PPT物件&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;Dim&lt;/span&gt; pptIndex &lt;span class="kwrd"&gt;As&lt;/span&gt; Presentation, pptToOpen &lt;span class="kwrd"&gt;As&lt;/span&gt; Presentation&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;Set&lt;/span&gt; pptIndex = ActivePresentation&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;/pre&gt;&lt;pre&gt;    &lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="rem"&gt;&amp;#39;一些工作用變數&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;Dim&lt;/span&gt; I &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Integer&lt;/span&gt;, S &lt;span class="kwrd"&gt;As&lt;/span&gt; Slide, ImgFile &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;Dim&lt;/span&gt; iGlobalIndex &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Integer&lt;/span&gt;, iIndexPerPage &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Integer&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;Dim&lt;/span&gt; iPngWidth &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Integer&lt;/span&gt;, iPngHeight &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Integer&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;Dim&lt;/span&gt; sldIndex &lt;span class="kwrd"&gt;As&lt;/span&gt; Slide, picInserted &lt;span class="kwrd"&gt;As&lt;/span&gt; Shape&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;Dim&lt;/span&gt; iDimCount &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Integer&lt;/span&gt;, iIndexAtPage &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Integer&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;/pre&gt;&lt;pre&gt;    &lt;span class="rem"&gt;&amp;#39;先將有投影片清除，只留下最後一張，並清除其內容&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;While&lt;/span&gt; pptIndex.Slides.Count &amp;gt; 1&lt;/pre&gt;&lt;pre&gt;        pptIndex.Slides(1).Delete&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;Wend&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;Set&lt;/span&gt; sldIndex = pptIndex.Slides(1)&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;While&lt;/span&gt; (sldIndex.Shapes.Count &amp;gt; 0)&lt;/pre&gt;&lt;pre&gt;        sldIndex.Shapes(1).Delete&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;Wend&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="rem"&gt;&amp;#39;複雜空白頁配置供後續新增時使用&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;Dim&lt;/span&gt; pptLayout &lt;span class="kwrd"&gt;As&lt;/span&gt; CustomLayout&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;Set&lt;/span&gt; pptLayout = pptIndex.Slides(1).CustomLayout&lt;/pre&gt;&lt;pre&gt;    &lt;/pre&gt;&lt;pre class="alt"&gt;    iIndexPerPage = 4&lt;/pre&gt;&lt;pre&gt;    &lt;/pre&gt;&lt;pre class="alt"&gt;    iDimCount = iIndexPerPage ^ 0.5&lt;/pre&gt;&lt;pre&gt;    iPngWidth = pptIndex.PageSetup.SlideWidth / iDimCount&lt;/pre&gt;&lt;pre class="alt"&gt;    iPngHeight = pptIndex.PageSetup.SlideHeight / iDimCount&lt;/pre&gt;&lt;pre&gt;    iGlobalIndex = 0&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;/pre&gt;&lt;pre&gt;    &lt;span class="rem"&gt;&amp;#39;列出待處理PPT的目錄及檔案物件&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;Dim&lt;/span&gt; SourceFolder &lt;span class="kwrd"&gt;As&lt;/span&gt; Scripting.Folder&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;Dim&lt;/span&gt; FileItem &lt;span class="kwrd"&gt;As&lt;/span&gt; Scripting.File&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;/pre&gt;&lt;pre&gt;    &lt;span class="rem"&gt;&amp;#39;列舉檔案清單&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;Set&lt;/span&gt; SourceFolder = FSO.GetFolder(sCurrentPath &amp;amp; &lt;span class="str"&gt;&amp;quot;\Slides&amp;quot;&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;For&lt;/span&gt; &lt;span class="kwrd"&gt;Each&lt;/span&gt; FileItem &lt;span class="kwrd"&gt;In&lt;/span&gt; SourceFolder.Files&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;&amp;#39;排除索引PPT本身&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;If&lt;/span&gt; InStr(LCase(FileItem.Name), &lt;span class="str"&gt;&amp;quot;index&amp;quot;&lt;/span&gt;) = 0 &lt;span class="kwrd"&gt;Then&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;&amp;#39;開啟檔案&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                &lt;span class="kwrd"&gt;Set&lt;/span&gt; pptToOpen = Presentations.Open(FileItem.Path, WithWindow:=msoFalse)&lt;/pre&gt;&lt;pre class="alt"&gt;            I = 0&lt;/pre&gt;&lt;pre&gt;            ImgFile = sTempPath &amp;amp; &lt;span class="str"&gt;&amp;quot;\&amp;quot;&lt;/span&gt; &amp;amp; Split(FileItem.Name, &lt;span class="str"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;)(0) &amp;amp; &lt;span class="str"&gt;&amp;quot;_&amp;quot;&lt;/span&gt; &amp;amp; I &amp;amp; &lt;span class="str"&gt;&amp;quot;.png&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;For&lt;/span&gt; &lt;span class="kwrd"&gt;Each&lt;/span&gt; S &lt;span class="kwrd"&gt;In&lt;/span&gt; pptToOpen.Slides&lt;/pre&gt;&lt;pre&gt;            &lt;/pre&gt;&lt;pre class="alt"&gt;                iIndexAtPage = iGlobalIndex &lt;span class="kwrd"&gt;Mod&lt;/span&gt; iIndexPerPage&lt;/pre&gt;&lt;pre&gt;                &lt;span class="rem"&gt;&amp;#39;索引檔加入新投影片&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;If&lt;/span&gt; (iIndexAtPage = 0) &lt;span class="kwrd"&gt;Then&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="kwrd"&gt;Set&lt;/span&gt; sldIndex = pptIndex.Slides.AddSlide(pptIndex.Slides.Count, pptLayout)&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                &lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="rem"&gt;&amp;#39;將投影片匯出成暫存PNG&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                S.Export ImgFile, FilterName:=&lt;span class="str"&gt;&amp;quot;PNG&amp;quot;&lt;/span&gt;, _&lt;/pre&gt;&lt;pre class="alt"&gt;                         ScaleWidth:=iPngWidth * 1.2, ScaleHeight:=iPngHeight * 1.2&lt;/pre&gt;&lt;pre&gt;                &lt;span class="rem"&gt;&amp;#39;插入圖片&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;Set&lt;/span&gt; picInserted = sldIndex.Shapes.AddPicture(ImgFile, Linktofile:=msoFalse, _&lt;/pre&gt;&lt;pre&gt;                                  SaveWithDocument:=msoTrue, _&lt;/pre&gt;&lt;pre class="alt"&gt;                                  Left:=(iIndexAtPage &lt;span class="kwrd"&gt;Mod&lt;/span&gt; iDimCount) * iPngWidth, _&lt;/pre&gt;&lt;pre&gt;                                  Top:=(iIndexAtPage \ iDimCount) * iPngHeight, _&lt;/pre&gt;&lt;pre class="alt"&gt;                                  Width:=iPngWidth, Height:=iPngHeight)&lt;/pre&gt;&lt;pre&gt;                &lt;span class="rem"&gt;&amp;#39;加上連至PPT的超連結&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;With&lt;/span&gt; picInserted.ActionSettings(ppMouseClick)&lt;/pre&gt;&lt;pre&gt;                    .Action = ppActionHyperlink&lt;/pre&gt;&lt;pre class="alt"&gt;                    .Hyperlink.Address = FileItem.Name&lt;/pre&gt;&lt;pre&gt;                &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;With&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                I = I + 1&lt;/pre&gt;&lt;pre&gt;                iGlobalIndex = iGlobalIndex + 1&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;Next&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            &lt;span class="rem"&gt;&amp;#39;關閉PPT檔，刪除暫存圖檔&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            pptToOpen.Close&lt;/pre&gt;&lt;pre&gt;            FSO.DeleteFile ImgFile&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;Next&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;/pre&gt;&lt;pre&gt;    &lt;span class="rem"&gt;&amp;#39;儲存索引檔&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    pptIndex.SaveCopyAs sCurrentPath &amp;amp; &lt;span class="str"&gt;&amp;quot;\Slides\Index.ppt&amp;quot;&lt;/span&gt;, _&lt;/pre&gt;&lt;pre&gt;                        ppSaveAsOpenXMLPresentation, msoFalse&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6125/original.aspx" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;產生的索引PPT如上圖所示，在縮圖上按右鍵再選&amp;quot;開啟超連結&amp;quot;就可以打開投影片來源檔案。有需要的朋友請自取參考。&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6132" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/CODE/default.aspx">CODE</category></item><item><title>關於PowerPoint的笨問題-如何選取被藏在下方的物件</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/03/15/6118.aspx</link><pubDate>Mon, 15 Mar 2010 02:50:44 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6118</guid><dc:creator>Jeffrey</dc:creator><slash:comments>7</slash:comments><description>&lt;p&gt;我覺得這是一個笨問題，說出來會被人恥笑，不過找到解法很開心，還是決定PO文一篇以示紀念。&lt;/p&gt; &lt;p&gt;最近這陣子重操舊業，做起了弄投影片準備簡報的買賣。為了能生動地說明一些技術細節，我搞了幾個複雜的動畫展示(，其中不乏先顯示圖片1，按一下滑鼠出現圖片2蓋過圖片1的設計。&lt;/p&gt; &lt;p&gt;這種效果對PowerPoint來說是小事一椿，但我老被一個問題困擾: 當我把圖片2放在圖片1上方並完全蓋掉圖片1後，要如何選取圖片1調位置對我來說就是爆難的挑戰。我唯一會的解法，是先把蓋在上面的圖片2拖開好讓圖片1露出來，選取調整位置後再把圖片2蓋回去；如果蓋了三四層，就要改成一邊碎唸，一邊像剝洋葱一樣，逐層拖開，再逐層蓋回去。&lt;/p&gt; &lt;p&gt;拿個實例來說明: 投影片有兩張圖，&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2007/10/01/1138.aspx"&gt;海角單車&lt;/a&gt;圖的圖層順序在&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/06/23/natural.aspx"&gt;螳螂捕蟬&lt;/a&gt;圖上方&lt;/p&gt; &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6116/original.aspx" alt="" /&gt;&lt;/p&gt; &lt;p&gt;當螳螂躲到海角天涯之後(如下圖)，再點一下其他地方，選取框便會消失，從此看不到也點不到，請問要怎麼把它再抓出來調位置? &lt;/p&gt; &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6117/original.aspx" alt="" /&gt;&lt;/p&gt; &lt;p&gt;答案出奇簡單:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font color="#ff8000" size="4"&gt;按Tab鍵就好了呀，笨蛋!!&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;我笨了好幾年，真的。&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6118" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Tips/default.aspx">Tips</category></item><item><title>我的MCE體驗</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/03/14/mce-experience.aspx</link><pubDate>Sun, 14 Mar 2010 00:49:23 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6113</guid><dc:creator>Jeffrey</dc:creator><slash:comments>4</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;還記得我那台在客廳&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/02/21/ahci-slow-hd.aspx"&gt;找到職場第二春&lt;/a&gt;的XPC SB81P嗎? 前些時候突發奇想，心想既然放在客廳還接了電視，何不加塊電視卡讓它具有錄影功能? 再加上Windows 7 Ultimate內建了&lt;a href="http://windows.microsoft.com/zh-TW/windows7/products/features/windows-media-center"&gt;Windows Media Center&lt;/a&gt;(但我還是習慣叫它&lt;a href="http://www.microsoft.com/hk/windowsxp/mediacenter/default.mspx"&gt;MCE&lt;/a&gt;)，如此才真能成為名符其實的娛樂中心。&lt;/p&gt;  &lt;p&gt;弄來一塊退役的電視卡UPG301 BTR(在拍賣網站只值&lt;a href="http://goods.ruten.com.tw/item/show?11090501986606"&gt;100元&lt;/a&gt;，可以想見其又老又不中用的程度)，反正是無償取得，就胡亂玩玩。這麼老的TV卡片，最新的驅動程式只到XP用WDM版，但Windows 7竟出乎意外的親切隨和，WDM Driver也照單全收，裝完後，Media Center居然還真偵測到這塊電視卡。&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6109/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;坦白說，在電腦裡看到電視畫面讓人有點小興奮。但畢竟這是張行將就木的老卡，當年技術較不成熟，縱使卡上有顆超大鐵殼包著的TV Tuner，但大部分頻道畫質極差，有些頻道雜訊多到直逼&amp;quot;色盲檢定表&amp;quot;的地步~~ 再者，或許因為驅動程式問題，只看得到影像沒有聲音。但這些都不是最嚴重的問題...&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6111/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;老伯伯電視卡每次重啟Media Center後只提供六秒鐘的功能展示，就會出現低位元速率錯誤後停止服務，提醒你: 如果滿意在電腦上看電視的感覺，記得要花錢哦~~~&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6110/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;於是，被這個有影無聲的類色盲檢定打動(或者該說被刺激到)，冒險走了趟&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/11/30/5735.aspx"&gt;恐怖的光華商場&lt;/a&gt;，買了一塊支援硬體壓縮的新版電視卡-&lt;a href="http://www.comprousa.com/tw/product/h900f/h900f.html"&gt;Vista H900F&lt;/a&gt;。&lt;/p&gt;  &lt;p&gt;科技日新月益，新TV卡上的Tuner縮到只比50元銅板略大些(老TV卡上的Tuner鐵殼體積直逼牛奶糖外盒，參考圖片: &lt;a href="http://forum.coolaler.com/showthread.php?t=174619"&gt;1&lt;/a&gt;, &lt;a href="http://goods.ruten.com.tw/item/show?11090501986606"&gt;2&lt;/a&gt;)，但畫質卻異常清晰，跟直接接電視的效果相當。&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6112/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;試用了一個星期感覺良好，以下是我覺得用Windws Media Center看電視的好處:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;首推當然是預錄功能!      &lt;br /&gt;直接在節目表上找到播放時間，電腦就會自動醒來錄影，錄完又自己回去睡。       &lt;br /&gt;我愛用錄影的目的其實並非怕錯過某些節目，而是企圖更有效率地應用時間。把&amp;quot;較有價值&amp;quot;的節目保留下來，當有時間坐在沙發上看電視時，直接看些有營養的東西，好過握著搖控器一台轉過一台，漫無目的Channel Surfing，&amp;quot;看電視&amp;quot;這件事才會變得更有意義。(謎之聲: 意義是三小... 黑暗: 不要來亂，小心我把你弄死!)       &lt;br /&gt;舉個例子，昨天小朋友吵著想看電視，當時幼幼台正在播兒子常看的戰龍四驅卡通，但最後被我說服改看預錄好的百萬小學堂。我覺得能更自主的選擇要值得看的節目，比隨遇而安亂看一通來得更積極正面。 &lt;/li&gt;    &lt;li&gt;看錄影節目還有另一項好處: 可以隨時中斷再繼續，不怕被打斷(有小孩的人就知道這點有多重要)，而廣告部分可以直接跳過的功能也很迷人。(我還想要有一顆向前快轉3分鐘或5分鐘的快捷鈕) &lt;/li&gt;    &lt;li&gt;最後，&lt;a href="http://www.nownews.com/2005/10/21/327-1859437.htm"&gt;時光平移&lt;/a&gt;功能在觀賞即時節目時很讚，可以回頭重播剛才遺漏或沒看清楚的部分，就不怕被人打斷了(有小孩的人就知道這點有多重要)。 &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;但目前有個棘手問題，由於要預錄節目，電腦得長期保持在休眠狀態，已經關掉了滑鼠、鍵盤、網卡的喚醒功能，但電腦仍常無故自己醒來(最近連續三天早上6:37分醒來，莫非是老年人的症頭?)，另外設定固定時間後休眠的功能也常未如預期生效。這個議題就交給茶包射手，過陣子請他再跟大家報告。&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6113" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Windows+7/default.aspx">Windows 7</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/MCE/default.aspx">MCE</category></item><item><title>LINQ應用實例-對字串陣列元素逐一做處理</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/03/11/linq-demo.aspx</link><pubDate>Thu, 11 Mar 2010 11:11:02 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6107</guid><dc:creator>Jeffrey</dc:creator><slash:comments>1</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;今天有個需求，要將某目錄下的圖檔清單轉成Javascript字串陣列，以方便網頁處理。例如: B:\100311\目錄下有F1.gif, F2.gif, F3.gif三個圖檔，便要產出var data = [&amp;quot;F1.gif&amp;quot;,&amp;quot;F2.gif&amp;quot;,&amp;quot;F3.gif&amp;quot;];，心血來潮，分別列出傳統組字串寫法、String.Join及應用LINQ概念的程式碼比較一番。&lt;/p&gt; &lt;div class="BlogCodeBlock"&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class="alt"&gt;    StringBuilder sb = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder();&lt;/pre&gt;&lt;pre&gt;    &lt;span class="rem"&gt;//傳統寫法&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    sb.Append(&lt;span class="str"&gt;&amp;quot;var data = [&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;bool&lt;/span&gt; addComma = &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; f &lt;span class="kwrd"&gt;in&lt;/span&gt; Directory.GetFiles(&lt;span class="str"&gt;&amp;quot;B:\\100311&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;*.gif&amp;quot;&lt;/span&gt;))&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt; pureFileName = Path.GetFileName(f);&lt;/pre&gt;&lt;pre&gt;        sb.AppendFormat(&lt;span class="str"&gt;&amp;quot;{0}\&amp;quot;{1}\&amp;quot;&amp;quot;&lt;/span&gt;, addComma ? &lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt; : &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;, pureFileName);&lt;/pre&gt;&lt;pre class="alt"&gt;        addComma = &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;    sb.Append(&lt;span class="str"&gt;&amp;quot;];&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;    Debug.WriteLine(sb.ToString());&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="rem"&gt;//用String.Join&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    sb.Length = 0;&lt;/pre&gt;&lt;pre&gt;    sb.Append(&lt;span class="str"&gt;&amp;quot;var data = [&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;    List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; l = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;();&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; f &lt;span class="kwrd"&gt;in&lt;/span&gt; Directory.GetFiles(&lt;span class="str"&gt;&amp;quot;B:\\100311&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;*.gif&amp;quot;&lt;/span&gt;))&lt;/pre&gt;&lt;pre class="alt"&gt;        l.Add(&lt;span class="str"&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt; + Path.GetFileName(f) + &lt;span class="str"&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;    sb.Append(&lt;span class="kwrd"&gt;string&lt;/span&gt;.Join(&lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;, l.ToArray()));&lt;/pre&gt;&lt;pre class="alt"&gt;    sb.Append(&lt;span class="str"&gt;&amp;quot;];&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;    Debug.WriteLine(sb.ToString());&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="rem"&gt;//使用LINQ概念，程式碼可以簡化成一行&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; r = &lt;span class="str"&gt;&amp;quot;var data = [&amp;quot;&lt;/span&gt; +&lt;/pre&gt;&lt;pre&gt;                &lt;span class="kwrd"&gt;string&lt;/span&gt;.Join(&lt;span class="str"&gt;&amp;quot;,&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;                    Directory.GetFiles(&lt;span class="str"&gt;&amp;quot;b:\\100311&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;*.gif&amp;quot;&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="rem"&gt;//利用Select()對陣列做處理，只保留檔名部分，前後加上雙引號&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                    .Select(s =&amp;gt; &lt;span class="str"&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt; + Path.GetFileName(s) + &lt;span class="str"&gt;&amp;quot;\&amp;quot;&amp;quot;&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="rem"&gt;//轉回字串陣列&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                    .ToArray()) + &lt;span class="str"&gt;&amp;quot;];&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;    Debug.WriteLine(r);&lt;/pre&gt;&lt;pre class="alt"&gt;    Console.Read();&lt;/pre&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Directory.GetFiles()傳回的string[]，在.NET 3.5中可呼叫Select()配合&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/06/13/lambda-expression.aspx"&gt;Lambda&lt;/a&gt;表示法，直接將檔名中的路徑部分去掉，並在前後加上雙引號後，再透過.ToArray()傳回處理過的字串陣列，這樣就連foreach迴圈都免了。&lt;/p&gt;
&lt;p&gt;程式碼變簡潔了(一行搞定，連StringBuilder都用不到)，但看懂Code的門檻也變高，簡潔度及親和性如何取捨，大家再視狀況自行斟酌吧!&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6107" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/.NET/default.aspx">.NET</category></item><item><title>模擬iPhone瀏覽網頁</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/03/11/iphone-browser-emulator.aspx</link><pubDate>Wed, 10 Mar 2010 20:54:49 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6105</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;先前介紹過&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/03/07/test-web-with-wm-emulator.aspx"&gt;用Windows Mobile模擬器測試網頁&lt;/a&gt;的做法。但依目前市場的態勢，評估行動裝置上網卻漏了iPhone，就像炒菜鍋行銷企劃只找辣妹做問卷調查、卻不去了解歐巴桑的偏好一般可笑。(謎之聲: 你該不會以為舉這種酸溜溜的比喻，WM市場就會變大，只會.NET的老頭就會變值錢吧? 黑暗: 沒辦法，誰叫我是&lt;a href="http://www.plurk.com/p/3zgfb5"&gt;謝團長&lt;/a&gt;...)&lt;/p&gt;  &lt;p&gt;依我的了解，iPhone模擬器只能在iMac機器上執行，沒投資硬體就想模擬? 門都沒有!! 不過，幸好我們只需模擬iPhone瀏覽網頁，問題比較單純。簡單在網路上找了一下，發現善心人士提供的工具:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://www.aviassin.com/iphonedrift"&gt;iPhone Drift&lt;/a&gt;       &lt;br /&gt;模擬了iPhone的Safari、YouTube、Google Maps，還可以旋轉檢視橫向效果，功能挺齊備的，而程式有一個不到1M的執行檔，用起來很方便。       &lt;br /&gt;&lt;img class="PopBoxImageSmall" src="http://blog.darkthread.net/photos/darkthread/images/6103/500x375.aspx" alt="" /&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://labs.blackbaud.com/NetCommunity/article?artid=662"&gt;iBBDemo&lt;/a&gt;       &lt;br /&gt;由於iPhone的Safari與Windows版Safari都是用Webkit作為核心，因此作者透過客製的CSS Extension，就能在Windows上模擬出iPhone Safari的瀏覽效果。比較特別的是它還模擬了iPhone的螢幕鍵盤輸入畫面，但純示意罷了，無法真的用來輸入。[&lt;a href="http://labs.blackbaud.com/ibbdemo/ibbdemo.html"&gt;展示影片&lt;/a&gt;]       &lt;br /&gt;&lt;img class="PopBoxImageSmall" src="http://blog.darkthread.net/photos/darkthread/images/6104/500x375.aspx" alt="" /&gt; &lt;/li&gt;    &lt;li&gt;也有線上版本的iPhone瀏覽器模擬，例如: &lt;a href="http://www.testiphone.com/"&gt;TestiPhone.com&lt;/a&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;透過上述的方法，就可以在Windows上測試iPhone Browser的瀏覽效果囉~~&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff8000"&gt;【補充】&lt;/font&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;iPhone的Safari不支援Flash、Java等，我測試的結果iPhoneDrift會攔下Flash但Java Applet則闖關成功、iBBDemo則是擋了Java放行Flash，小心此點對結果正確性的影響。&lt;/li&gt;    &lt;li&gt;模擬器在Windows上的執行速度不會跟實體機器一致(多半效能會比手機好)，在評估操作流暢度時建議納入考量。 &lt;/li&gt; &lt;/ul&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6105" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Mobile/default.aspx">Mobile</category></item><item><title>jQuery 1.4 Solved The OnChange Event Issue of IE AutoComplete</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/03/08/jquery1-4-fix-autocomplete-onchange-issue.aspx</link><pubDate>Mon, 08 Mar 2010 13:36:00 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6093</guid><dc:creator>Jeffrey</dc:creator><slash:comments>6</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;IE&amp;#39;s AutoComplete feature doesn&amp;#39;t trigger onchange event is a well-known &amp;quot;by-design&amp;quot; behaviour:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms533032%28VS.85%29.aspx"&gt;Using AutoComplete in HTML Forms&lt;/a&gt;&lt;br /&gt;&lt;i&gt;To determine when a user updates the content of a field from the AutoComplete dialog box, use the &lt;/i&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms536956%28VS.85%29.aspx"&gt;&lt;i&gt;onpropertychange&lt;/i&gt;&lt;/a&gt;&lt;i&gt; event, rather than the &lt;/i&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms536912%28VS.85%29.aspx"&gt;&lt;i&gt;onchange&lt;/i&gt;&lt;/a&gt;&lt;i&gt; event, because the &lt;b&gt;onchange&lt;/b&gt; event does not fire.&lt;/i&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;I have ever found some fixes (example &lt;a href="http://jehiah.cz/archive/onchange-and-autocomplete"&gt;1&lt;/a&gt;, &lt;a href="https://mootools.lighthouseapp.com/projects/2706/tickets/568-autocomplete-dont-fire-onchange-event-ie"&gt;2&lt;/a&gt;) developed by community before. Today, when I managed to put them into my project, I found something interesting.&lt;/p&gt; &lt;p&gt;As using jQuery 1.4+, if I set change() event on a &amp;lt;input type=&amp;quot;text&amp;quot; /&amp;gt;, it will be triggered as well as the event declared by onchange=&amp;quot;...&amp;quot; when IE AutoComplete.&amp;nbsp; In the other word, jQuery 1.4 solved the &amp;quot;onchange not triggered&amp;quot; issue of IE AutoComplete.&lt;/p&gt; &lt;p&gt;After tracing the code roughly, I found jQuery uses some new mechanism: beforeactive event to store the original value in .data(&amp;quot;_chage_data&amp;quot;), compares it with current value in focusout event, if not equal, then trigger the onchange event...&amp;nbsp; I guess that&amp;#39;s why it can detect the value change when using IE AutoComplete.&lt;/p&gt; &lt;p&gt;So, using jQuery 1.4+, you can solved the well-known &amp;quot;No OnChange Event When IE AutoComplete&amp;quot; issue easily!&lt;/p&gt; &lt;p&gt;Here is my simple test case.&amp;nbsp; When jQuery 1.3.2 is included, no change event will be fired when using IE AutoComplete to fill t1, t2 value.&amp;nbsp;&amp;nbsp; After changing the link to jQuery 1.4.2, you will find AutoComplete on t1 can trigger both &amp;quot;T1 JS change&amp;quot; and &amp;quot;T1 jQuery change&amp;quot; now.&lt;/p&gt; &lt;div class="BlogCodeBlock"&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="asp"&gt;&amp;lt;%@ Page Language=&amp;quot;C#&amp;quot; AutoEventWireup=&amp;quot;true&amp;quot; %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;head&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;#39;text/javascript&amp;#39;&lt;/span&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="attr"&gt;src&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;#39;http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js&amp;#39;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&amp;lt;!--  &amp;lt;script type=&lt;span class="str"&gt;&amp;#39;text/javascript&amp;#39;&lt;/span&gt; &lt;/pre&gt;&lt;pre class="alt"&gt;src=&lt;span class="str"&gt;&amp;#39;http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js&amp;#39;&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt; --&amp;gt;&lt;/pre&gt;&lt;pre&gt;    &amp;lt;script type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;function&lt;/span&gt; output(msg) {&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;var&lt;/span&gt; disp = document.getElementById(&lt;span class="str"&gt;&amp;quot;disp&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;            disp.innerHTML += &lt;span class="str"&gt;&amp;quot;&amp;lt;li&amp;gt;&amp;quot;&lt;/span&gt; + msg;&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt;        $(&lt;span class="kwrd"&gt;function&lt;/span&gt;() {&lt;/pre&gt;&lt;pre&gt;            &lt;span class="rem"&gt;//if you set change event on #t1 with jQuery 1.4.2,&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;//the onchange event will be triggered when using AutoComplete&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            $(&lt;span class="str"&gt;&amp;quot;#t1&amp;quot;&lt;/span&gt;).change(&lt;span class="kwrd"&gt;function&lt;/span&gt;() {&lt;/pre&gt;&lt;pre class="alt"&gt;                output(&lt;span class="str"&gt;&amp;quot;T1 jQuery change&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;            });&lt;/pre&gt;&lt;pre class="alt"&gt;        });&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;head&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt; &lt;span class="attr"&gt;method&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;post&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;T1: &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;t1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;t1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;onchange&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;output(&amp;#39;T1 JS change&amp;#39;);&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;br&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;T2: &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;t2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;t2&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;onchange&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;output(&amp;#39;T2 JS change&amp;#39;);&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;br&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;submit&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Submit&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;disp&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;font color="#ff8000"&gt;【中文摘要】&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;上回試著要&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/03/05/set-autocomp-off.aspx"&gt;用autocomplete=&amp;quot;off&amp;quot;法&lt;/a&gt;解決IE自動完成時&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/01/26/change-event-not-fired.aspx"&gt;onchange事件不會被觸發&lt;/a&gt;的老問題，不過如同91在回饋裡所言--要關閉使用者慣用的自動完成功能，就得向User解釋這個難以啟齒的技術鳥問題。萬一不幸遇上&amp;quot;角頭級&amp;quot;的使用者，哪可能耐著性子聽你說什麼IE自動完成、onchange這些鬼東西，只怕會換來一句--&amp;quot;&lt;font color="#ff8000"&gt;onchange是三小，恁爸只聽過回家吃自己，沒聽過onchange啦!&lt;/font&gt;&amp;quot;... 想到這個畫面，我忽然不寒而慄，決定花時間研究一下怎麼讓AutoComplete也觸發change事件。&lt;/p&gt;
&lt;p&gt;開了個小專案寫了jQuery做測試，卻發現一件有趣的事。AutoComplete竟會觸發onchange事件~~~ 是我眼花了還是腦筋不清楚? 明明上回驗證過，像鐵一般的事實這回怎麼來了個急轉彎? 在做了一堆測試比對後，總算釐清一件事實:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font color="#ff8000"&gt;使用jQuery 1.4設定&amp;lt;input type=&amp;quot;text&amp;quot;&amp;gt;的change()事件後，使用IE AutoComplete也會觸發onchange事件!!&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;我做了一個簡單的測試案例(程式碼在上方)來驗證這點: 首先使用jQuery-1.3.2，用IE自動完成填入t1, t2的資料，並不會觸發onchange事件；改用jQuery-1.4.2後，再以自動完成為t1, t2填入資料, 這回有加掛jQuery chnage()事件的t1會觸發用jQuery及用onchange=&amp;quot;...&amp;quot;宣告的事件，而t2則不會。&lt;/p&gt;
&lt;p&gt;粗略地追了一下程式碼，發現jQuery-1.4在change事件觸發機制上做了改良: 在beforeactive事件時會將原值存在.data(&amp;quot;_chage_data&amp;quot;)、在focusout事件中會用它跟現值比對，不一致時則觸發change事件。這跟我原本想出的解法差不多，而jQuery在核心中已實踐了類似的邏輯，應該就是無形中修好&amp;quot;AutoComplete不觸發OnChange事件&amp;quot;問題的原因。&lt;/p&gt;
&lt;p&gt;總之，不費吹灰之力就修好這個惱人的問題，有賺到的感覺，哈!!&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6093" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/English/default.aspx">English</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/jQuery/default.aspx">jQuery</category></item><item><title>利用Windows Mobile模擬器測試網頁</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/03/07/test-web-with-wm-emulator.aspx</link><pubDate>Sun, 07 Mar 2010 06:59:00 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6089</guid><dc:creator>Jeffrey</dc:creator><slash:comments>1</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;上回介紹過&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/03/04/dev-emu-mgr-standalone.aspx"&gt;獨立安裝Windows Mobile 6模擬器&lt;/a&gt;的方法，最終目標是想利用模擬器測試網站在行動裝置上的呈現與操作效果，今天繼續補完後續步驟。&lt;/p&gt;  &lt;p&gt;首先，我們來讓模擬器可以&amp;quot;上網&amp;quot;。要讓模擬器連上Internet，透過VPC 2007的虛擬網卡驅動程式是&lt;a href="http://msmvps.com/blogs/jeffloucks/archive/2009/09/08/emulating-windows-mobile-6-5-with-networking.aspx"&gt;一種方法&lt;/a&gt;，不過必須安裝VPC 2007，會有平台上的限制，所以像Windows 7、Windows 2007 R2就被發了好人卡；我個人偏愛的是另一種做法---透過&lt;a href="http://www.microsoft.com/taiwan/windowsmobile/devicecenter.mspx"&gt;Mobile Device Center&lt;/a&gt;轉接(就是ActiveSync在Vista之後進化版)。&lt;/p&gt;&lt;p&gt;&lt;font color="#ff0000"&gt;[2010-03-08補充]&lt;/font&gt; 網友guest提供在Windows 7上獨立安裝模擬器所需Virtual Machine Network Services的&lt;a href="http://www.brianpeek.com/blog/archive/2009/05/02/windows-virtual-pc-and-the-microsoft-device-emulator.aspx"&gt;密技&lt;/a&gt;，可以克服Win7上無法安裝VPC2007的問題，特此感謝!&lt;/p&gt;  &lt;p&gt;為了讓模擬器連上Mobile Device Center，我們要先開放DMA連線(如下圖)。另外，網路選項要設成Automatic或The Internet，以允許模擬器連到Internet。有一個小撇步: 當發現模擬器無法連上Internet時(完全連不到或變成連上本機IIS)，在Automatic/The Internet間做一次切換常能解決問題，我不知背後原理為何，大家就姑且當成&amp;quot;電視沒訊號時用力搥一下就會變好&amp;quot;那種密技吧!&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6083/500x375.aspx" class="PopBoxImageSmall" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;設定好Mobile Device Center，接著在Device Emulator Manager啟動模擬器的&amp;quot;Cradle”功能，模擬實體手機/PDA用USB連上電腦的樣子。&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6082/500x375.aspx" class="PopBoxImageSmall" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;接著Mobile Device Center就會偵測到模擬器連上線了(Connected)，由於我們不需要同步模擬器的行事曆、連絡人，其他功能可以忽略不理。&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6084/500x375.aspx" class="PopBoxImageSmall" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;如果沒有意外，此時在模擬器裡開啟IE，就可以開連上平日常逛網站，看看它們在手機上變成什麼&lt;strike&gt;鬼樣子&lt;/strike&gt;德行囉! (密技提示: &lt;font color="#ff8000"&gt;發現無法連線時，記得用力拍一下電視機 &lt;/font&gt;XD)&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6085/500x375.aspx" class="PopBoxImageSmall" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;另外，在智慧手機界，使用Opera Mobile或Opera Mini的使用者很多，所以理論上也該裝一套來玩玩。安裝Opera最快的方法是用直接用模擬器開IE連上&lt;a href="http://m.opera.com/next"&gt;http://m.opera.com/next&lt;/a&gt;，下載Cab檔案回來安裝就搞定了。&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6086/500x375.aspx" class="PopBoxImageSmall" alt="" /&gt;&amp;nbsp;&amp;nbsp; &lt;img src="http://blog.darkthread.net/photos/darkthread/images/6087/500x375.aspx" class="PopBoxImageSmall" alt="" /&gt;&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6089" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Mobile/default.aspx">Mobile</category></item><item><title>Mini C# Lab 1.4 Release</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/03/05/mini-c-lab-1-4.aspx</link><pubDate>Fri, 05 Mar 2010 09:29:21 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6078</guid><dc:creator>Jeffrey</dc:creator><slash:comments>3</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;The primary new feature of Ver 1.4 is &lt;b&gt;batch mode&lt;/b&gt;!&lt;/p&gt; &lt;p&gt;Now you can run Mini C# Lab program as a scheduled task, no UI interactivity is needed. Here are some batch argument examples:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Load and execute x:\temp\test.cs, use the output to overwrie x:\temp\log.txt &lt;b&gt;&lt;br /&gt;MiniCSharpLab /batch /cs:x:\temp\test.cs /out:x:\temp\log.txt /overwrite&lt;/b&gt;  &lt;li&gt;Load and execute &amp;quot;c:\some path\test.cs&amp;quot;, append the output to LogyyyyMMdd.txt (the file name will be change according to System.DateTime.Now) &lt;br /&gt;&lt;b&gt;MiniCSharpLab /batch /cs:&amp;quot;&amp;quot;c:\some path\test.cs&amp;quot;&amp;quot; /out:Log{yyyyMMdd}.txt&lt;/b&gt;  &lt;li&gt;Load and execute x:\aa.cs, append the output to x:\aa.txt, if execution time is longer than 1200 seconds, program will be terminated. &lt;br /&gt;&lt;b&gt;MiniCSharpLab /batch /cs:x:\aa.cs /out:x:\aa.txt /timeout:1200&lt;/b&gt;  &lt;li&gt;Load and execute x:\aa.vb as .NET 3.5 program, append the output to x:\aa.txt &lt;br /&gt;&lt;b&gt;MiniCSharpLab /batch /vb:x:\aa.vb /out:x:\aa.txt /v35&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;There are also minor bug fix and improvement:  &lt;ol&gt; &lt;li&gt;Fix: Thread.Sleep for 0.5&amp;quot; after execution to avoid output loss (I hope it works)  &lt;li&gt;Add: Add execution duration display&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;&lt;font color="#ff8000"&gt;【中文說明】&lt;/font&gt;&lt;/p&gt; &lt;p&gt;其實1.4版已經寫出來蠻久了，上回的&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/09/02/coding-for-fun-contest-start.aspx"&gt;黑暗盃程式魔人賽&lt;/a&gt;裡就已經偷跑過了。今天剛好跟同事提到要寫簡單的Script跑排程，索性一不做二不休，把它Release到&lt;a href="http://minicsharplab.codeplex.com/releases/view/41445"&gt;CodePlex網站&lt;/a&gt;上，想參考程式的人也可以在CodePlex找到原始碼。&lt;/p&gt; &lt;p&gt;1.4版最大的特色是支援批次無UI的方式執行，這個之前網友Ammon也有提過，剛好也是我自己不少排程作業上的需求。執行參數如下:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;載入並執行x:\temp\test.cs, 輸出結果覆寫到x:\temp\log.txt&lt;br /&gt;&lt;b&gt;MiniCSharpLab /batch /cs:x:\temp\test.cs /out:x:\temp\log.txt /overwrite&lt;/b&gt;  &lt;li&gt;載入並執行&amp;quot;c:\some path\test.cs&amp;quot;, 輸入結果附加到LogyyyyMMdd.txt檔案後端(檔名會隨執行時間變化) &lt;br /&gt;&lt;b&gt;MiniCSharpLab /batch /cs:&amp;quot;&amp;quot;c:\some path\test.cs&amp;quot;&amp;quot; /out:Log{yyyyMMdd}.txt&lt;/b&gt;  &lt;li&gt;載入並執行x:\aa.cs, 輸出結果附加到x:\aa.txt。若執行時間超過1200秒，會被強制中止&lt;br /&gt;&lt;b&gt;MiniCSharpLab /batch /cs:x:\aa.cs /out:x:\aa.txt /timeout:1200&lt;/b&gt;  &lt;li&gt;載入x:\aa.vb，視為.NET 3.5程式執行，輸出結果附加到x:\aa.txt&lt;br /&gt;&lt;b&gt;MiniCSharpLab /batch /vb:x:\aa.vb /out:x:\aa.txt /v35&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;strong&gt;另外還有兩個小修改:&lt;/strong&gt;&lt;/p&gt; &lt;li&gt;修正: 加入0.5秒Thread.Sleep延遲，防止輸出結果遺失(希望有效)  &lt;li&gt;加入執行時間顯示功能&lt;/li&gt; &lt;p&gt;如發現Bug或有功能建議，歡迎在此留言回饋。(但不一定能即時修正或擴充，請見諒!)&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6078" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Tools/default.aspx">Tools</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/English/default.aspx">English</category></item><item><title>CODE-鎖定有掛onchange事件的欄位停用自動完成</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/03/05/set-autocomp-off.aspx</link><pubDate>Fri, 05 Mar 2010 05:56:00 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6075</guid><dc:creator>Jeffrey</dc:creator><slash:comments>2</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;上回提過因使用IE自動完成&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/01/26/change-event-not-fired.aspx"&gt;造成onchange事件不被觸發&lt;/a&gt;的問題，著實帶來一些困擾，不少User抱怨系統掛在onchange事件的欄位連動功能失效。雖然User漸漸都已學會在這些欄位使用手工輸入，不要依賴IE自動完成帶入結果就可以避開問題，抱怨日少。不過我想從網頁設定上去停用autocomplete還是比較根本的解決之道。&lt;/p&gt; &lt;p&gt;當然，我們可以抱著寧可錯殺一百，不可錯放一個的精神來個$(&amp;quot;input:text&amp;quot;).attr(&amp;quot;autocomplete&amp;quot;, &amp;quot;off&amp;quot;)，把網頁上所有&amp;lt;input type=&amp;#39;text&amp;#39;&amp;gt;的自動完成功能全都閹掉，一了百了。不過，我習慣處理得細膩一點，將這個不得已措施的範圍縮小到受影響的欄位上，換句話說，只有掛了onchange事件的&amp;lt;input type=&amp;#39;text&amp;#39;&amp;gt;才是要撲殺的對象。&lt;/p&gt; &lt;p&gt;要怎麼偵錯欄位是否有掛onchange事件? 想起上回剛好玩過&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/01/23/list-jquery-events.aspx"&gt;列舉元素已掛載的jQuery事件&lt;/a&gt;的小把戲，這回把它融合進來，就做出了這個&amp;quot;標靶治療式&amp;quot;的autocomplete屬性停用Plugin。&lt;/p&gt; &lt;p&gt;以下的程式範例可以讓大家拿去&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/02/15/mini-jquery-lab-online.aspx"&gt;Mini jQuery Lab&lt;/a&gt;實地玩一下。&lt;/p&gt; &lt;div class="BlogCodeBlock"&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;//針對有掛onchange的&amp;lt;input type=&amp;quot;text&amp;quot;&amp;gt;設定autocomplete=&amp;quot;off&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;//參考: http://tinyurl.com/yzwp3lt&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;//限制: 只對執行當下已經掛載onchange事件者有效(不包含.live()掛載者)&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;$.fn.disableAutoCompleteForChange = &lt;span class="kwrd"&gt;function&lt;/span&gt;(force) {&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="rem"&gt;//過濾只留下&amp;lt;input type=&amp;#39;text&amp;#39;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;this&lt;/span&gt;.filter(&lt;span class="str"&gt;&amp;quot;:text&amp;quot;&lt;/span&gt;).each(&lt;span class="kwrd"&gt;function&lt;/span&gt;() {&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//篩選有掛change事件者, 參考: http://tinyurl.com/yka6x8g&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;var&lt;/span&gt; evts = $.data(&lt;span class="kwrd"&gt;this&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;events&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (force || evts &amp;amp;&amp;amp; evts[&lt;span class="str"&gt;&amp;quot;change&amp;quot;&lt;/span&gt;] || &lt;span class="kwrd"&gt;this&lt;/span&gt;.onchange != undefined)&lt;/pre&gt;&lt;pre&gt;            $(&lt;span class="kwrd"&gt;this&lt;/span&gt;).attr(&lt;span class="str"&gt;&amp;quot;autocomplete&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;off&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="rem"&gt;//.val(&amp;quot;SET&amp;quot;); //可加上這段測試是否被設定&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    });&lt;/pre&gt;&lt;pre class="alt"&gt;}&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;//加入三個&amp;lt;input&amp;gt;進行測試, T2用jQuery掛onchange, T3直接宣告onchange&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;$(&lt;span class="str"&gt;&amp;quot;body&amp;quot;&lt;/span&gt;).append(&lt;span class="str"&gt;&amp;quot;&amp;lt;input id=&amp;#39;T1&amp;#39; /&amp;gt;&amp;lt;input id=&amp;#39;T2&amp;#39; /&amp;gt;&amp;quot;&lt;/span&gt;)&lt;/pre&gt;&lt;pre&gt;.append(&lt;span class="str"&gt;&amp;quot;&amp;lt;input id=&amp;#39;T3&amp;#39; onchange=&amp;#39;alert(3);&amp;#39; /&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;$(&lt;span class="str"&gt;&amp;quot;#T2&amp;quot;&lt;/span&gt;).change(&lt;span class="kwrd"&gt;function&lt;/span&gt;() { alert(&lt;span class="str"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;); });&lt;/pre&gt;&lt;pre&gt;$(&lt;span class="str"&gt;&amp;quot;input&amp;quot;&lt;/span&gt;).disableAutoCompleteForChange();&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;注意:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;.disableAutoCompleteForChange()的呼叫時機要在onchange掛上去後&lt;/li&gt;
&lt;li&gt;對使用.live()掛載的onchange無效&lt;/li&gt;
&lt;li&gt;另外多加對以&amp;lt;input onchange=&amp;quot;...&amp;quot; /&amp;gt;方式掛上事件的偵測&lt;/li&gt;
&lt;li&gt;.disableAutoCompleteForChange(true)時可不管有無onchange，一律停用&lt;/li&gt;&lt;/ol&gt;&lt;font color="#ff6600"&gt;[2010-03-08補充] &lt;/font&gt;測試發現使用jQuery 1.4+掛載change()事件即可&lt;a href="http://bit.ly/aLOD7j"&gt;解決此問題&lt;/a&gt;&lt;br /&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6075" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/IE/default.aspx">IE</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/CODE/default.aspx">CODE</category></item><item><title>獨立安裝Windows Mobile 6模擬器</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/03/04/dev-emu-mgr-standalone.aspx</link><pubDate>Wed, 03 Mar 2010 20:31:21 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6074</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;Visual Studio 2005/2008提供了整合式的Windows Mobile程式開發環境，其中包含&lt;strong&gt;PocketPC及Windows Mobile平台模擬器&lt;/strong&gt;，可以在沒有實體手機/PDA的情況下執行、測試及偵錯程式。不過VS2008內附的模擬器只支援到Windows Mobile 5.0，如果想測試WM6，則需安裝&lt;a href="http://www.microsoft.com/downloads/info.aspx?na=47&amp;amp;p=1&amp;amp;SrcDisplayLang=en&amp;amp;SrcCategoryId=&amp;amp;SrcFamilyId=20686a1d-97a8-4f80-bc6a-ae010e085a6e&amp;amp;u=details.aspx%3ffamilyid%3d06111A3A-A651-4745-88EF-3D48091A390B%26displaylang%3den"&gt;Windows Mobile 6 Professional and Standard Software Development Kits Refresh&lt;/a&gt; (Standard / Profession分成兩包，視需要分別下載安裝) ，而要測試中文環境的話，則還要另外下載&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=38C46AA8-1DD7-426F-A913-4F370A65A582&amp;amp;displaylang=en"&gt;正體中文版的Windows Mobile 6 ROM Image&lt;/a&gt;，安裝完成後Device Emulator Manager就會自動多出WM6平台可供選擇，非常直覺簡單:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6053/original.aspx" alt="" /&gt;     &lt;br /&gt;圖1 從VS2008啟動Device Emulator Manager&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6054/original.aspx" alt="" /&gt;&amp;#160; &lt;br /&gt;圖2 安裝WM6 SDK及正體中文WM6 Image後，會多出WM6平台選項&lt;/p&gt;  &lt;p&gt;手上有台跑Windows 7的ThinkPad T43，沒安裝VS2008(只有VS2010 RC)，但我想在上面跑WM6模擬器，用WM6的IE瀏覽器測試網頁在行動裝置上的呈現效果。少了VS2008一手包辦自動裝到好的貼心協助，獨立安裝需要較多的手工。以下是我試出來的步驟:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;下載安裝&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=a6f6adaf-12e3-4b2f-a394-356e2c2fb114&amp;amp;displaylang=en"&gt;Microsoft Device Emulator 3.0 -- Standalone Release&lt;/a&gt;， C:\Program Files\Microsoft Device Emulator\1.0\dvcemumanager.exe就是圖1 Device Emulator Manager的執行程式，建議在桌面做個捷徑方便啟動。 (註: 模擬器使用與Virtual PC相似的核心技術，所以不能裝在VM OS上) &lt;/li&gt;    &lt;li&gt;下載安裝&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=38C46AA8-1DD7-426F-A913-4F370A65A582&amp;amp;displaylang=en"&gt;正體中文版的Windows Mobile 6 ROM Image&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;此時執行Device Emulator Manager的結果可能會讓你失望，清單上空空如也，剛才新裝的WM6 Image並不會自動列出來(這種時候就會覺得Visual Studio就甘心A)。我們需要設法產生一個.decfg檔案，提供Emulator Manager足夠的資訊，才能順利啟動WM6模擬器。最簡單的方法是找台有裝VS2008的機器，在圖2介面上先選取模擬器，按右鍵用Save As產生.decfg檔再修改(多半只需調整檔案路徑)。 &lt;/li&gt;    &lt;li&gt;將上一步驟產生的.decfg檔案Copy到C:\Users\&lt;em&gt;使用者名稱&lt;/em&gt;\Documents\My Device Emulators目錄下，重新啟動一次Device Emulator Manager，就可以看見新增的模擬器，按右鍵選Connect…       &lt;br /&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6055/original.aspx" alt="" /&gt;       &lt;br /&gt;薑! 薑! 薑! 薑~~~ WM6模擬器就跑起來囉! &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;檢附上述的WM6ProCHT.decfg供參:&lt;/p&gt;  &lt;div style="background-color:#000000;color:#00ff00;"&gt;   &lt;p&gt;&amp;lt;DeviceEmulator xmlns=&amp;quot;&lt;a href="http://schemas.microsoft.com/DeviceEmulator/2006/01/DeCfg&amp;quot;"&gt;http://schemas.microsoft.com/DeviceEmulator/2006/01/DeCfg&amp;quot;&lt;/a&gt;&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Board&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;CpuCore Reconfigurable=&amp;quot;false&amp;quot;&amp;gt;ARMv4&amp;lt;/CpuCore&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;CpuOptions Reconfigurable=&amp;quot;false&amp;quot;&amp;gt;TDI&amp;lt;/CpuOptions&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;VFP Reconfigurable=&amp;quot;false&amp;quot;&amp;gt;false&amp;lt;/VFP&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;OSImage Reconfigurable=&amp;quot;false&amp;quot; Address=&amp;quot;0&amp;quot;&amp;gt;C:\Program Files\Windows Mobile 6 SDK\PocketPC\DeviceEmulation\0404\PPC_CHT_GSM_VR.BIN&amp;lt;/OSImage&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;MemSize Reconfigurable=&amp;quot;false&amp;quot;&amp;gt;128&amp;lt;/MemSize&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Board&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Emulator&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;DefaultSave Reconfigurable=&amp;quot;false&amp;quot;&amp;gt;true&amp;lt;/DefaultSave&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;FuncKey Reconfigurable=&amp;quot;true&amp;quot;&amp;gt;193&amp;lt;/FuncKey&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;HostKey Reconfigurable=&amp;quot;true&amp;quot;&amp;gt;Right-Alt&amp;lt;/HostKey&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Language Reconfigurable=&amp;quot;false&amp;quot;&amp;gt;1028&amp;lt;/Language&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Skin Reconfigurable=&amp;quot;true&amp;quot; EnableSkin=&amp;quot;true&amp;quot; ToolTips=&amp;quot;off&amp;quot;&amp;gt;C:\Program Files\Windows Mobile 6 SDK\PocketPC\DeviceEmulation\Pocket_PC_Phone\Pocket_PC_PE.xml&amp;lt;/Skin&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;VMID Reconfigurable=&amp;quot;false&amp;quot;&amp;gt;{984B347D-C615-4042-856D-EF567D2721C2}&amp;lt;/VMID&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Emulator&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Peripherals&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;SerialPort Reconfigurable=&amp;quot;true&amp;quot; UARTNumber=&amp;quot;0&amp;quot;&amp;gt;none&amp;lt;/SerialPort&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;SerialPort Reconfigurable=&amp;quot;true&amp;quot; UARTNumber=&amp;quot;1&amp;quot;&amp;gt;none&amp;lt;/SerialPort&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;SerialPort Reconfigurable=&amp;quot;true&amp;quot; UARTNumber=&amp;quot;2&amp;quot;&amp;gt;none&amp;lt;/SerialPort&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Peripherals&amp;gt;       &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Platform&amp;gt;Windows Mobile 6 Professional SDK&amp;lt;/Platform&amp;gt;       &lt;br /&gt;&amp;lt;/DeviceEmulator&amp;gt;&lt;/p&gt; &lt;/div&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6074" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Mobile/default.aspx">Mobile</category></item><item><title>開啟RSClientPrint偵錯Log</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/03/02/rsclientprint-log.aspx</link><pubDate>Tue, 02 Mar 2010 02:00:47 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6070</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;Reporting Service線上列印功能可以直接由網頁列印出美美的報表，是很酷的功能，不過實務應用也遇過不少小狀態就是了。&lt;/p&gt; &lt;p&gt;昨天無意中發現RSClientPrint元件支援寫Log檔的功能，這在射茶包時可是價值連城的情報。故特別PO文做個筆記以防年老失憶:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;開啟Log記錄的做法是用RegEdit加入一則機碼(Key)HKEY_CURRENT_USER\Software\Microsoft\Microsoft SQL Server\80\Reporting Services&lt;br /&gt;並新增LogRSClientPrintInfo REG_DWORD = 0x00000001(可參考&lt;a href="http://support.microsoft.com/kb/907010/en-us"&gt;這篇KB&lt;/a&gt;More Inforation一節的說明)&lt;/li&gt; &lt;li&gt;執行SSRS報表並使用線上列印&lt;/li&gt; &lt;li&gt;DIR %temp%\LOG*.tmp，便可看到剛才列印動作所產生的Log檔案(檔名格式為LOGnnnn.tmp，nnnn為16進位隨機數字)。&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;稍微看了一下，Log裡記載的資訊蠻詳細的，開啟報表路徑/名稱、使用語系、選擇的印表機、換頁、發出Request的過程都鉅細靡遺地被保留下來，很有Debug Log的味道，我想對於解決RSClientPrint疑難雜症應該很有幫忙。不過要看到這些Log，RSClientPrint元件至少要被順利載入並啟動才可以，RSClientPrint另一個常見的問題是因版本更新導致無法載入使用，這裡也順便提供一下參考資訊:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/07/24/rsclientprint-error-again.aspx"&gt;【茶包射手專欄】又見SSRS無法列印問題&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/10/30/rsclientprint-issue-again.aspx"&gt;KB-三探Windows Update後SSRS不能列印問題&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/10/24/ssrs-print-issue-final.aspx"&gt;KB-再探Windows Update後SSRS不能列印問題&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/10/16/ssrs-client-print-control-error.aspx"&gt;【茶包射手專欄】SSRS報表網頁列印失敗&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6070" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Reporting+Service/default.aspx">Reporting Service</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Trouble-Shooting/default.aspx">Trouble-Shooting</category></item><item><title>【茶包射手日記】不限條件選項之SQL組裝與資料庫OR運算特性驗證</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/03/02/or-operator-in-sql.aspx</link><pubDate>Mon, 01 Mar 2010 13:38:44 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6065</guid><dc:creator>Jeffrey</dc:creator><slash:comments>7</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;在設計查詢介面時，下拉式選單是很常見的條件選取方式，而往往我們都會再加上一個&amp;quot;不限條件&amp;quot;選項，允許使用者不限制條件，列出所有項頁。舉例來說: 在設定查詢地區的下拉選單(例如: ddlArea)，除了列出基隆市、台北市、台北縣、桃園縣...等各縣市Option外，常會再多一個&amp;quot;所有地區&amp;quot;選項，將Option Value設定=&amp;#39;*&amp;#39;，選取時表示不限定地區。在Server端，便要將這些篩選條件轉為SQL指令，如何將&amp;#39;*&amp;#39;視為不限地區? 我過去都用條件式動態組裝:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font color="#ff8000"&gt;if (ddlArea.Text != &amp;quot;*&amp;quot;) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cmd.CommandText += &amp;quot; AND AreaCol = @pArea&amp;quot;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cmd.Parameters.Add(&amp;quot;@pArea&amp;quot;, SqlDbType.NVarChar).Value = ddlArea.Text;&lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;後來有一天開了竅，想到更簡潔的寫法:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font color="#ff8000"&gt;cmd.CommandText = @&amp;quot;&lt;br /&gt;SELECT .... FROM ...&lt;br /&gt;WHER ...其他查詢條件...&lt;br /&gt;AND (@pArea = &amp;#39;*&amp;#39; OR AreaCol = @pArea)&lt;br /&gt;....&amp;quot;;&lt;br /&gt;cmd.Parameters.Add(&amp;quot;@pArea&amp;quot;, SqlDbType.NVarChar).Value = ddlArea.Text;&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;如此，整個查詢條件可以直接寫成靜態字串，便於閱讀修改，不必視狀況決定是否要傳入@pArea，而它一樣可達到傳入&amp;quot;*&amp;quot;就不設地區比對條件的效果。&lt;/p&gt; &lt;p&gt;今天在噗浪上與噗友討論到類似議題，看到一種新寫法: where p1 = case @p1 when &amp;#39;*&amp;#39; then p1 else @p1 end，噗友提到曾經聽某資料庫老師說過，這種寫法比上述OR法效能更好，理由是在SQL指令中，OR 的兩邊條件都會做運算比較，跟一般程式的認知不同。(不過噗友對此理論也抱持懷疑態度就是了)&lt;/p&gt; &lt;p&gt;基本上，我無法接受SQL指令中OR兩邊都會執行的主張。當今各家DB在效能優化上不遺餘力，每一個環節錙銖必較，怎麼可能留下這麼個大洞害人摔跤? 不過要怎麼驗證它倒是挺傷腦筋的。&lt;/p&gt; &lt;p&gt;想到一個好辦法，用Block機制來突顯差別!! 故意在OR後方條件式中SELECT一個被Lock住的Table，接著故意讓OR前方條件為True，若SQL傻不楞登硬要執行OR後方條件式就會被擋下來，直到Lock被釋放為止(ROLLBACK TRAN/COMMIT TRAN)；若SQL如我想的冰雪聰明，就會直接忽略OR後方條件立刻送回結果。由結果出現時機，便可判定OR後方的條件式是否被執行。&lt;/p&gt; &lt;p&gt;實驗結果如下: (SQL 2008 @ Windows 2008 x64)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6064/original.aspx" alt="" /&gt;&lt;/p&gt; &lt;p&gt;在最下方的SQL指令區故意INSERT卻不COMMIT讓T2被Lock住，此時OR前方條件為1=1的SQL指令不受影響，OR前方為1=0的SQL指令才會執行到第二條件SELECT COUNT(ID) FROM T2而被Block住。由此可證: SQL Sever並不會像VB6一樣傻傻地檢查全部的AND/OR條件式，後方條件式執行與否會視前面的結果而定，故前述的OR法大家可安心服用。(這裡有&lt;a href="http://stackoverflow.com/questions/1649237/equivalent-to-vb-andalso-in-sql"&gt;另一篇討論&lt;/a&gt;也持相同看法: The query engine will take care of this for you. All operators will &amp;quot;short circuit&amp;quot; if they can.) &lt;/p&gt; &lt;p&gt;&lt;font color="#ff8000" size="4" face="Tahoma"&gt;MYTH BUSTED!!!&lt;/font&gt; &lt;a href="http://en.wikipedia.org/wiki/MythBusters"&gt;[註]&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6065" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/SQL+2005/default.aspx">SQL 2005</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Trouble-Shooting/default.aspx">Trouble-Shooting</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/SQL+2000/default.aspx">SQL 2000</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/SQL+2008/default.aspx">SQL 2008</category></item><item><title>【黑暗水電工日記】假戲真做!</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/02/28/call-me-dark-plumber.aspx</link><pubDate>Sun, 28 Feb 2010 04:41:00 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6062</guid><dc:creator>Jeffrey</dc:creator><slash:comments>1</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6060/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;樓梯間的天花板燈座年代久遠，塑膠逐漸脆化，前陣子更是開始座盤分離，接著就出現接觸不良的狀態。開燈後常得用雨傘尖輕推燈泡&amp;quot;喬&amp;quot;個幾下才能點亮，上週一，小燈座走到了生命盡頭，再也亮不起來。樓梯少了燈，晚上出入不便，身為&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/04/05/dark-plumber.aspx"&gt;黑暗水電工&lt;/a&gt;，面對這種險惡情境，當然責無旁貸要扛起拯救世界的重責大任! (遠目)&lt;/p&gt;  &lt;p&gt;平日下班都己晚上，樓梯間昏暗難以施工，於是趁著週末，先去附近的&amp;quot;專業水電材料行&amp;quot;(不是一般水電行，是專做&amp;quot;專業水電工&amp;quot;生意的水電材料批發店家，也是上回買到&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2007/05/12/756.aspx"&gt;止水墊&lt;/a&gt;的地方)&lt;strike&gt;進貨&lt;/strike&gt;買材料。材料行內成天都有&amp;quot;專業水電工&amp;quot;進出，用行話直接跟老板下單，像&amp;quot;LP4來50個&amp;quot;、&amp;quot;有六分管嗎&amp;quot;之類的，我雖然跟水電工前輩們一樣穿著排汗衫牛仔褲，但只要一開口說找&amp;quot;樓梯間天花板用的那種燈泡座&amp;quot;，偽水電工的身份馬上穿幫。不過，水電材料行的所有商品都標了價，老板沒打算坑殺外行人(比起上回&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/01/25/life-twitter-201001.aspx"&gt;想賣我高檔汽車大燈燈泡&lt;/a&gt;的店家好多了)，讓我買起來很安心。以下這兩個燈座，大家猜猜看多少錢?&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6056/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;一個10元，很便宜吧! &lt;/p&gt;  &lt;p&gt;搬來木梯，抄起起子卸螺絲、拆舊燈座、裝新燈座、旋緊螺絲，三兩下便換裝完成。看來拆換燈座對我根本是小菜一碟，請叫我【黑暗水電工】!!&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6057/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;完工後站在梯子上，等黑暗女王開關燈檢測功能是否正常。此時發生了一件震憾我&lt;strike&gt;幼小&lt;/strike&gt;脆弱心靈的大事...&lt;/p&gt;  &lt;p&gt;樓下傳來鐵門開門聲，原來是住樓上的老先生回來了。木梯卡住狹小的樓梯轉角，要由梯子旁的狹小間隙側身穿過有點為難老人家，於是我趕緊將木梯收合讓出路來。老先生跟我點頭道謝繼續向上走，看到正在家門口控制電燈開關的黑暗女王，隨口說了一句:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#ff8000"&gt;妳找水電來換燈哦~&lt;/font&gt;&lt;font color="#ff8000"&gt;妳&lt;/font&gt;&lt;font color="#ff8000"&gt;找水電來換燈哦~&lt;/font&gt;&lt;font color="#ff8000"&gt;妳&lt;/font&gt;&lt;font color="#ff8000"&gt;找水電來換燈哦~&lt;/font&gt;&lt;font color="#ff8000"&gt;妳&lt;/font&gt;&lt;font color="#ff8000"&gt;找水電來換燈哦~&lt;/font&gt;&lt;font color="#ff8000"&gt;妳&lt;/font&gt;&lt;font color="#ff8000"&gt;找水電來換燈哦~&lt;/font&gt;&lt;font color="#ff8000"&gt;妳&lt;/font&gt;&lt;font color="#ff8000"&gt;找水電來換燈哦~&lt;/font&gt;&lt;font color="#ff8000"&gt;妳&lt;/font&gt;&lt;font color="#ff8000"&gt;找水電來換燈哦~&lt;/font&gt;&lt;font color="#ff8000"&gt;妳&lt;/font&gt;&lt;font color="#ff8000"&gt;找水電來換燈哦~&lt;/font&gt;&lt;font color="#ff8000"&gt;妳&lt;/font&gt;&lt;font color="#ff8000"&gt;找水電來換燈哦~~~~~~&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;但見女王強忍笑意，努力克制不自主抖動的身體，回答老先生: &amp;quot;沒有啦，我先生看燈壞了，就想換一換...&amp;quot;&lt;/p&gt;  &lt;p&gt;老大爺，我說&amp;quot;叫我【黑暗水電工】&amp;quot;只是玩笑話，您怎麼當真啦!! 沒想到，我這個&amp;quot;偽．水電工&amp;quot;入戲太深，今天有排汗衫+牛仔褲的加持，全身已開始散放出濃濃的&amp;quot;水電工味&amp;quot;，竟順利騙倒鄰居。真不知該為練成&amp;quot;二轉水電工&amp;quot;高興，還是該擔心這會對我繼續從事&amp;quot;專業資訊工作&amp;quot;形成隱憂?&lt;/p&gt;  &lt;p&gt;一切都是幻覺，嚇不倒我的。&lt;/p&gt;  &lt;p&gt;平復好受驚的心情，在此向大家介紹前陣子在光華商場挖到的寶--八合一折疊起子! 比起過去買過的換頭起子優秀許多，最大的好處是不需額外空間收納起子頭，而且起子前端一體成形跟標準起子一樣細長，不像抽換式起子前端的突出六角套筒座常會卡住螺絲孔，伸不進去轉螺絲。&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6059/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;還有，起子前端的7顆LED燈在照明不足的場合超級好用，大推!!&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6058/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;這麼順手俐落的兵刃，絕對是水電工作人員居家旅遊，不可或缺的良伴，只要100塊大洋，有空要去光華敗家的捧油們可以考慮帶一把回家。&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6062" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Life/default.aspx">Life</category></item><item><title>遲來一週的Acer P224W箱文</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/02/28/6061.aspx</link><pubDate>Sun, 28 Feb 2010 04:32:39 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6061</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;&lt;font color="#ff8000"&gt;【註: 文中有標明[p]的連結為噗浪訊息】&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;故事要從2008年11月說起，家裡有一台LKK的三鳥牌17&amp;quot; LCD，在&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/11/18/3799.aspx"&gt;添購新的22&amp;quot;內建電視盒LCD&lt;/a&gt;後，高齡8歲的它在我公司的辦公桌覓得第二春，轉任工作機的第二螢幕。&lt;/p&gt;  &lt;p&gt;時間來到半年後，7月的一天早上，17&amp;quot; LCD忽然出現&lt;a href="http://www.plurk.com/p/1k5nmj" target="_blank"&gt;一條血紅垂直線&lt;/a&gt;[p]。當時，全黑桌面背景配上紅線，還真有Canon L鏡的高級fu呢! 讓我心生莫名的&lt;a href="http://www.plurk.com/p/1kb3tk" target="_blank"&gt;虛榮感&lt;/a&gt;[p]~~~&lt;/p&gt;  &lt;p&gt;可惜，代誌嘸像憨人想A哈尼甘單~~~ 兩個月後，&lt;a href="http://www.plurk.com/p/2esd6t" target="_blank"&gt;第二條紅色線&lt;/a&gt;[p]冒出來了，噗友預言，線會愈來愈多，然後不久就會掛點。果不其然，&lt;a href="http://www.plurk.com/p/2h783d" target="_blank"&gt;第三條&lt;/a&gt;[p]、&lt;a href="http://www.plurk.com/p/2km8k9" target="_blank"&gt;第四條&lt;/a&gt;[p]、&lt;a href="http://www.plurk.com/p/35dyp6" target="_blank"&gt;第五條&lt;/a&gt;[p]陸續出現，還開始不定期出現消失加變色，我想這一定是傳說中稀有的隱藏版LCD--&lt;strong&gt;轉吧轉吧七彩霓虹線17&amp;quot;變色龍系列&lt;/strong&gt;!!&lt;/p&gt;  &lt;p&gt;經過一段時間磨合，螢幕線條開始穩定，固定顯示三條。AskaSu提醒我，三條槓意義非凡，這台螢幕肯定是萬中選一、全球僅有，唯一掛上尉階的LCD，從此它博得&amp;quot;&lt;a href="http://www.plurk.com/p/35yemp" target="_blank"&gt;上尉LCD&lt;/a&gt;[p]&amp;quot;的稱號。&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6016/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;雖然擁有一台掛階LCD挺酷的，但為了防止它無預警退役，我還是展開新LCD的Survey。一開始想衝1920*1080 FullHD解析度，一方面它是市場目前的主流，選擇多競爭大價格優，而超大的可使用桌面也有利於寫程式，只是有個問題--點距! &lt;/p&gt;  &lt;p&gt;點距指螢幕上點與點之間的距離。在解析度相同的前題下，用個比喻，就像一模一樣兩千字的文章，印成A4大小的點距會比縮小印成B5來得大，字看起來較大，閱讀較不費力。粗略的點距算法是 吋數 / (水平線數^2+垂直線數^2) ^ 0.5 / 2.54。[&lt;a href="http://www.pcdvd.com.tw/showthread.php?t=808123" target="_blank"&gt;參考&lt;/a&gt;]&lt;/p&gt;  &lt;p&gt;以我原來的工作機螢幕組合來說，19&amp;quot; + 17&amp;quot;，兩台都設成1280*1024解析度，而二者的點距就有段距離，以髮蒼蒼視茫茫中年人的標準，19&amp;quot;的點距(0.0294)看起來比17&amp;quot;(0.0263)舒適不少。若同樣是1920*1080 FullHD，22&amp;quot;的點距是0.0253，23&amp;quot;是0.0265，24&amp;quot;是0.0276，26&amp;quot;是0.0299，換句話說，要到我偏愛的1280*1024 19&amp;quot;點距水準，FullHD得買到26&amp;quot;才會符合，再不然至少也要24&amp;quot;。這會有兩個問題，1) 我的辦公桌硬要擠下24&amp;quot; or 26&amp;quot; + 19&amp;quot;的組合會猶如阿婆生子--很拼 2) 有點擔心24&amp;quot;/26&amp;quot;大尺寸LCD對近距離長期使用有點太大(一直從左到右轉頭，讀完長篇大論Word文件時不知會不會扭傷脖子 XD) &lt;/p&gt;  &lt;p&gt;最後我決定退而求其次選1680，尺寸也退到22&amp;quot;。有兩個選擇: 16:9 (1680*945)或16:10 (1680*1050)? 在辦公室裡鮮少會有看16:9寬螢幕電影的需求，而垂直多出105個pixel高度，足足可以放下三條狀態列，對總是擠滿各式工具小視窗的IDE開發環境來說彌足珍貴。&lt;/p&gt;  &lt;p&gt;確定22&amp;quot; 1680*1050的規格後，趁著年假逛了PCHome，發現&lt;a href="http://shopping.pchome.com.tw/?mod=store&amp;amp;func=style_show&amp;amp;SR_NO=DSAB11" target="_blank"&gt;22&amp;quot; 16:10的選擇&lt;/a&gt;並不多，不用在幾十台符合規格中猶豫不決，反而是好事一椿。篩選條件很簡單，一定要有DVI，有HDMI更好，一堆便宜的純D-Sub款式立刻出局，很快地就決定了&lt;a href="http://shopping.pchome.com.tw/?mod=item&amp;amp;func=exhibit&amp;amp;IT_NO=DSAB02-A45215205&amp;amp;SR_NO=DSAB11&amp;amp;ROWNO=1" target="_blank"&gt;Acer P224W&lt;/a&gt;(剛才發現現在標價比上週調高三百元，頓時又多了賺到的感覺，XD)，這台螢幕有24h到貨服務，順便也讓我第一次體驗到&amp;quot;敗家於無形&amp;quot;的奧義--一時意亂情迷，頭腦還來不及清醒，小黑貓就已經叼著東西在門口等您...&lt;/p&gt;  &lt;p&gt;敗了家還沒圖沒真相是不被允許的，所以:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6015/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6014/original.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;講完了。&lt;/p&gt;  &lt;p&gt;什麼? 住在&lt;u&gt;開封&lt;/u&gt;的&lt;u&gt;艾凱香&lt;/u&gt;小姐Call In提問，為什麼只有這樣，根本就沒開箱? &lt;/p&gt;  &lt;p&gt;咳，請大家仔細看標題，本來就說是&amp;quot;P224W箱文&amp;quot;，並不是&amp;quot;P224W開箱文&amp;quot;，到此為止也是合情合理。&lt;/p&gt;  &lt;p&gt;使用心得還是得提一下: 經一週工作使用實測，各方面感覺良好，這是台好螢幕!&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6061" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Life/default.aspx">Life</category></item><item><title>TIPS-Windows 7便利貼(自黏便箋)快速鍵</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/02/26/win7-sticky-notes-key.aspx</link><pubDate>Fri, 26 Feb 2010 08:21:00 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6052</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;
&lt;p&gt;Windows 7內建了桌面便利貼軟體，或許基於商標專利或其他考慮，名字有些繞口--&lt;a href="http://windows.microsoft.com/zh-TW/windows7/products/features/sticky-notes"&gt;自黏便箋&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6051/original.aspx" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;相較於市場上其他便利貼軟體，它的功能有點陽春，介面也不怎麼順手。例如: 右鍵選單除了Copy/Paste跟換紙條底色外，找不到任何編輯文字內容的操作，也沒有工具列，一度讓我以為它只能當NotePad用。不過貼上去的內容倒是可以保留字型顏色，表示它的確支援RichText。爬了一下文，發現原來有密技! 雖然沒有按鈕工具列，但有一些快速鍵可以進行&amp;quot;簡單&amp;quot;的文字編輯操作。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ctrl + Shift + &amp;gt; : 字型變大 
&lt;li&gt;Ctrl + Shift + &amp;lt; : 字型變小 
&lt;li&gt;Ctrl + B : 粗體 
&lt;li&gt;Ctrl + I : 斜體 
&lt;li&gt;Ctrl + T : 刪字線 
&lt;li&gt;Ctrl + U : 底線 
&lt;li&gt;Ctrl + Shift + L : 按一次項目符號(Bulleted) 
&lt;li&gt;Ctrl + Shift + L : 按兩次自動編號(Numbered) 
&lt;li&gt;Ctrl + L : 靠左對齊 
&lt;li&gt;Ctrl + C : 靠中對齊 
&lt;li&gt;Ctrl + R : 靠右對齊&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;很可惜，想改字型跟顏色，還是門都沒有。&lt;/p&gt;
&lt;p&gt;如果不介意它的功能過於陽春、介面過於簡陋，Windows 7 User倒可試試這個不用安裝的內建便利貼。不過，我個人把它定位成免費奉送的小菜，針對這類需求，微軟真正的大餐是--&lt;a href="http://zh.wikipedia.org/zh-tw/Microsoft_OneNote"&gt;OneNote&lt;/a&gt;(OneNote是Office 2003/2007的家族成員之一，不過好像知名度並不高)，操作順手、功能華麗，用過的人評價都蠻高的，有興趣的人可以試試。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;font color="#ff8000"&gt;【不小心找到的其他技巧】&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.groovypost.com/howto/geek-stuff/effectively-use-windows-7-sticky-notes/"&gt;便利貼&lt;a href="http://www.groovypost.com/howto/geek-stuff/effectively-use-windows-7-sticky-notes/"&gt;過&lt;/a&gt;多時的快速排序法&lt;/li&gt;&lt;/ul&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6052" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Tips/default.aspx">Tips</category></item><item><title>POC-以jQuery實作會議室登記狀況顯示</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/02/25/jquery-booking-timeline.aspx</link><pubDate>Thu, 25 Feb 2010 07:56:00 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6045</guid><dc:creator>Jeffrey</dc:creator><slash:comments>1</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6044/500x375.aspx" class="PopBoxImageSmall" alt="" /&gt;&lt;/p&gt; &lt;p&gt;專案有個需求，要在網頁上呈現多間會議室一天的使用登記狀況。&amp;#39;傳統思維&amp;quot;可能會傾向用Table &amp;lt;td&amp;gt;模擬出時段區塊，然後將預約起迄時間範圍內的&amp;lt;td&amp;gt;用colspan併成一塊。不過如果要做到登記時間以10分鐘為單位，意味著每個小時要切割成6個&amp;lt;td&amp;gt;，即便沒有任何預約也是，讓Table充滿一堆無用又囉嗦的廢物Tag。加上計算哪幾個&amp;lt;td&amp;gt;要併在一起，得找出第一個&amp;lt;td&amp;gt;加colspan，並將後面&amp;lt;td&amp;gt;省略，演算法不怎麼單純。分析起來，這就是該用CSS取代Table做法實作Layout的經典情境。&lt;/p&gt; &lt;p&gt;寫了一段jQuery程式做出POC(Proof of Concept)供同事參考，示範使用DIV+CSS達成上述效果，並並盡可能簡化為呼叫函數就可以完成。一魚兩吃，PO出來供大家參考，順便蒐集諸位先進達人們的回饋指教。&lt;/p&gt; &lt;div class="BlogCodeBlock"&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;//輸入起/迄整點、寬、高及是否顯示時間標題列，傳回顯示全日時段狀態的&amp;lt;div&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; genTimeline(startHour, endHour, width, height, incHeader) {&lt;/pre&gt;&lt;pre class="alt"&gt;    $.Darkthread.tools.addDefaultStyles(&lt;span class="str"&gt;&amp;quot;.dttl_BookingBlock&amp;quot;&lt;/span&gt;, {&lt;/pre&gt;&lt;pre&gt;        &lt;span class="str"&gt;&amp;quot;.dttl_BookingBlock&amp;quot;&lt;/span&gt;: {&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;float&lt;/span&gt;: &lt;span class="str"&gt;&amp;quot;left&amp;quot;&lt;/span&gt;, position: &lt;span class="str"&gt;&amp;quot;absolute&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre&gt;            margin: &lt;span class="str"&gt;&amp;quot;0px&amp;quot;&lt;/span&gt;, padding: &lt;span class="str"&gt;&amp;quot;0px&amp;quot;&lt;/span&gt;, height: &lt;span class="str"&gt;&amp;quot;100%&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="str"&gt;&amp;quot;font-size&amp;quot;&lt;/span&gt;: &lt;span class="str"&gt;&amp;quot;9pt&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;background-color&amp;quot;&lt;/span&gt;: &lt;span class="str"&gt;&amp;quot;#dddddd&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre&gt;            &lt;span class="str"&gt;&amp;quot;border-left&amp;quot;&lt;/span&gt;: &lt;span class="str"&gt;&amp;quot;solid #444444 1px&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="str"&gt;&amp;quot;border-right&amp;quot;&lt;/span&gt;: &lt;span class="str"&gt;&amp;quot;solid #444444 1px&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        },&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="str"&gt;&amp;quot;.dttl_Timeline&amp;quot;&lt;/span&gt;: {&lt;/pre&gt;&lt;pre&gt;            border: &lt;span class="str"&gt;&amp;quot;solid black 1px&amp;quot;&lt;/span&gt;, position: &lt;span class="str"&gt;&amp;quot;relative&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        },&lt;/pre&gt;&lt;pre&gt;        &lt;span class="str"&gt;&amp;quot;.dttl_TimelineHeader&amp;quot;&lt;/span&gt;: {&lt;/pre&gt;&lt;pre class="alt"&gt;            border: &lt;span class="str"&gt;&amp;quot;solid black 1px&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre&gt;            backgroundColor: &lt;span class="str"&gt;&amp;quot;#dddddd&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="str"&gt;&amp;quot;font-size&amp;quot;&lt;/span&gt;: &lt;span class="str"&gt;&amp;quot;8pt&amp;quot;&lt;/span&gt;, position: &lt;span class="str"&gt;&amp;quot;relative&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        },&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="str"&gt;&amp;quot;.dttl_SplitLine&amp;quot;&lt;/span&gt;: {&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;float&lt;/span&gt;: &lt;span class="str"&gt;&amp;quot;left&amp;quot;&lt;/span&gt;, position: &lt;span class="str"&gt;&amp;quot;absolute&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="str"&gt;&amp;quot;border-left&amp;quot;&lt;/span&gt;: &lt;span class="str"&gt;&amp;quot;solid gray 1px&amp;quot;&lt;/span&gt;, &lt;/pre&gt;&lt;pre&gt;            width: &lt;span class="str"&gt;&amp;quot;1px&amp;quot;&lt;/span&gt;, height: &lt;span class="str"&gt;&amp;quot;100%&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt;    });&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; $tl = $(&lt;span class="str"&gt;&amp;quot;&amp;lt;div class=&amp;#39;dttl_Timeline&amp;#39; /&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;    $tl.height(height).width(width);&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; hourWidth = width / (endHour - startHour);&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; $h = $(&lt;span class="str"&gt;&amp;quot;&amp;lt;div /&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (incHeader)&lt;/pre&gt;&lt;pre class="alt"&gt;        $h.width(width).height(15).addClass(&lt;span class="str"&gt;&amp;quot;dttl_TimelineHeader&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;var&lt;/span&gt; i = startHour; i &amp;lt; endHour; i++) {&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;var&lt;/span&gt; vLine =&lt;/pre&gt;&lt;pre&gt;            &lt;span class="str"&gt;&amp;quot;&amp;lt;div class=&amp;#39;dttl_SplitLine&amp;#39; style=&amp;#39;left:&amp;quot;&lt;/span&gt; +&lt;/pre&gt;&lt;pre class="alt"&gt;            hourWidth * (i - startHour) + &lt;span class="str"&gt;&amp;quot;px;&amp;#39; /&amp;gt;&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;        $tl.append(vLine);&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (incHeader)&lt;/pre&gt;&lt;pre&gt;            $h.append(&lt;span class="str"&gt;&amp;quot;&amp;lt;div&amp;gt;&amp;quot;&lt;/span&gt; + i + &lt;span class="str"&gt;&amp;quot;&amp;lt;/div&amp;gt;&amp;quot;&lt;/span&gt;).append(vLine);&lt;/pre&gt;&lt;pre class="alt"&gt;    }&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (incHeader) {&lt;/pre&gt;&lt;pre class="alt"&gt;        $h.find(&lt;span class="str"&gt;&amp;quot;div&amp;quot;&lt;/span&gt;).css({&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;float&lt;/span&gt;: &lt;span class="str"&gt;&amp;quot;left&amp;quot;&lt;/span&gt;, margin: &lt;span class="str"&gt;&amp;quot;0px&amp;quot;&lt;/span&gt;, width: hourWidth + &lt;span class="str"&gt;&amp;quot;px&amp;quot;&lt;/span&gt;, &lt;/pre&gt;&lt;pre class="alt"&gt;            textAlign: &lt;span class="str"&gt;&amp;quot;center&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        });&lt;/pre&gt;&lt;pre class="alt"&gt;    }&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; $container = $(&lt;span class="str"&gt;&amp;quot;&amp;lt;div class=&amp;#39;dttl_Container&amp;#39; /&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;    $container.append($h).append($tl)&lt;/pre&gt;&lt;pre&gt;    .data(&lt;span class="str"&gt;&amp;quot;hourWidth&amp;quot;&lt;/span&gt;, hourWidth)&lt;/pre&gt;&lt;pre class="alt"&gt;    .data(&lt;span class="str"&gt;&amp;quot;startHour&amp;quot;&lt;/span&gt;, startHour)&lt;/pre&gt;&lt;pre&gt;    .data(&lt;span class="str"&gt;&amp;quot;endHour&amp;quot;&lt;/span&gt;, endHour);&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; $container;&lt;/pre&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;//display會直接顯示在方格中，可支援HTML語法&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;//detail以title=&amp;quot;...&amp;quot;方式處理，請給純文字&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;//cssOption可為css屬性物件，例如: { border:&amp;quot;...&amp;quot;, color:&amp;quot;...&amp;quot; }或是className&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;//會傳回&amp;lt;div&amp;gt; jQuery物件供後續應用&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; addBooking(timeline, startTime, endTime, display, detail, cssOption) {&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (cssOption == undefined || &lt;span class="kwrd"&gt;typeof&lt;/span&gt; cssOption == &lt;span class="str"&gt;&amp;quot;string&amp;quot;&lt;/span&gt;) &lt;/pre&gt;&lt;pre class="alt"&gt;        cssOption = { };&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; $tl = $(timeline);&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; sh = $tl.data(&lt;span class="str"&gt;&amp;quot;startHour&amp;quot;&lt;/span&gt;), eh = $tl.data(&lt;span class="str"&gt;&amp;quot;endHour&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="rem"&gt;//將時間先轉成小數&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; p = startTime.split(&lt;span class="str"&gt;&amp;#39;:&amp;#39;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; st = parseInt(p[0]) + (parseFloat(p[1]) / 60);&lt;/pre&gt;&lt;pre&gt;    &lt;span class="rem"&gt;//小於startHour, 以startHour為準&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (st &amp;lt; sh) st = sh;&lt;/pre&gt;&lt;pre&gt;    &lt;/pre&gt;&lt;pre class="alt"&gt;    p = endTime.split(&lt;span class="str"&gt;&amp;#39;:&amp;#39;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; et = parseInt(p[0]) + (parseFloat(p[1]) / 60);&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="rem"&gt;//大於endHour, 以endHour為準&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (et &amp;gt; eh) et = eh;&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="rem"&gt;//算出起始位置及寬度&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; hw = $tl.data(&lt;span class="str"&gt;&amp;quot;hourWidth&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; w = (et - st) * hw;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; x = (st - sh) * hw;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="rem"&gt;//加入顯示元素&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; $container = $tl.children(&lt;span class="str"&gt;&amp;quot;div:last&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;var&lt;/span&gt; $dv = $(&lt;span class="str"&gt;&amp;quot;&amp;lt;div class=\&amp;quot;dttl_BookingBlock\&amp;quot;/&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;    $dv.css(cssOption).css({ &lt;/pre&gt;&lt;pre&gt;        left: x + &lt;span class="str"&gt;&amp;quot;px&amp;quot;&lt;/span&gt;, width: w + &lt;span class="str"&gt;&amp;quot;px&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;        opacity: 0.7&lt;/pre&gt;&lt;pre&gt;    });&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;    $dv.html(&lt;span class="str"&gt;&amp;quot;&amp;lt;span style=&amp;#39;padding: 2px;&amp;#39;&amp;gt;&amp;quot;&lt;/span&gt; + display + &lt;span class="str"&gt;&amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;    .attr(&lt;span class="str"&gt;&amp;quot;title&amp;quot;&lt;/span&gt;, startTime + &lt;span class="str"&gt;&amp;quot;-&amp;quot;&lt;/span&gt; + endTime + &lt;span class="str"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt; + detail);&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;typeof&lt;/span&gt; cssOption == &lt;span class="str"&gt;&amp;quot;string&amp;quot;&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;        $dv.addClass(cssOption);&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;    $container.append($dv);&lt;/pre&gt;&lt;pre&gt;    &lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; $dv;&lt;/pre&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;以下是應用範例：&lt;/p&gt;
&lt;div class="BlogCodeBlock"&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;src&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;jquery-1.4.2.js&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&amp;lt;script src=&lt;span class="str"&gt;&amp;quot;jquery.darkthread.tools.js&amp;quot;&lt;/span&gt; type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;lt;script src=&lt;span class="str"&gt;&amp;quot;TimelineUtil.js&amp;quot;&lt;/span&gt; type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;&lt;pre&gt;&amp;lt;script type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&amp;gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    $(&lt;span class="kwrd"&gt;function&lt;/span&gt;() {&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;var&lt;/span&gt; $d = genTimeline(9, 21, 800, 30, &lt;span class="kwrd"&gt;true&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;        $(&lt;span class="str"&gt;&amp;quot;body&amp;quot;&lt;/span&gt;).append($d);&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;var&lt;/span&gt; $booking;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;//truncText可幫忙取前10個字            &lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;var&lt;/span&gt; longText = &lt;span class="str"&gt;&amp;quot;超長文字測試，利用truncDetail()取前10個字元&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;        $booking = addBooking($d, &lt;span class="str"&gt;&amp;quot;14:30&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;17:00&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;            $.Darkthread.tools.truncText(longText, 10), longText);&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;//允許重疊顯示&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        $booking = addBooking($d, &lt;span class="str"&gt;&amp;quot;16:30&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;20:00&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;來亂的&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;咬我呀!&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;&amp;nbsp; &lt;span class="rem"&gt;//cssOption可指定CSS&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;var&lt;/span&gt; cssOption = { backgroundColor: &lt;span class="str"&gt;&amp;quot;green&amp;quot;&lt;/span&gt;, color: &lt;span class="str"&gt;&amp;quot;yellow&amp;quot;&lt;/span&gt; };&lt;/pre&gt;&lt;pre&gt;        $booking = addBooking($d, &lt;span class="str"&gt;&amp;quot;09:30&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;10:00&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;Jeffrey&amp;quot;&lt;/span&gt;, &lt;/pre&gt;&lt;pre class="alt"&gt;                              &lt;span class="str"&gt;&amp;quot;重要會議&amp;quot;&lt;/span&gt;, cssOption);&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//cssOption傳入字串時，視為className&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        $booking = addBooking($d, &lt;span class="str"&gt;&amp;quot;10:30&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;12:00&amp;quot;&lt;/span&gt;, &lt;/pre&gt;&lt;pre class="alt"&gt;                                &lt;span class="str"&gt;&amp;quot;Meeting&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;MouseOver特效&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;booking&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;        &lt;span class="rem"&gt;//addBooking會傳回&amp;lt;div&amp;gt;的jQuery物件，可進行加上hover/click事件等操作&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        $booking.hover(&lt;span class="kwrd"&gt;function&lt;/span&gt;() {&lt;/pre&gt;&lt;pre&gt;            $(&lt;span class="kwrd"&gt;this&lt;/span&gt;).addClass(&lt;span class="str"&gt;&amp;quot;inverse&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;        }, &lt;span class="kwrd"&gt;function&lt;/span&gt;() {&lt;/pre&gt;&lt;pre&gt;            $(&lt;span class="kwrd"&gt;this&lt;/span&gt;).removeClass(&lt;span class="str"&gt;&amp;quot;inverse&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;        }).css(&lt;span class="str"&gt;&amp;quot;cursor&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;pointer&amp;quot;&lt;/span&gt;).click(&lt;span class="kwrd"&gt;function&lt;/span&gt;() {&lt;/pre&gt;&lt;pre&gt;            alert(&lt;span class="str"&gt;&amp;quot;Hi!&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;        });&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//產生100條時間軸各有12筆登錄，測試速度&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;var&lt;/span&gt; $tbl = $(&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="str"&gt;&amp;quot;&amp;lt;table cellspacing=&amp;#39;0&amp;#39; cellpadding=&amp;#39;0&amp;#39; style=&amp;#39;margin-top: 10px;&amp;#39; /&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;var&lt;/span&gt; i = 0; i &amp;lt; 100; i++) {&lt;/pre&gt;&lt;pre class="alt"&gt;            $tr = $(&lt;span class="str"&gt;&amp;quot;&amp;lt;tr&amp;gt;&amp;lt;td width=&amp;#39;10%&amp;#39; /&amp;gt;&amp;lt;td width=&amp;#39;90%&amp;#39; /&amp;gt;&amp;lt;/tr&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;            $tr.find(&lt;span class="str"&gt;&amp;quot;td:first&amp;quot;&lt;/span&gt;).text(&lt;span class="str"&gt;&amp;quot;Room&amp;quot;&lt;/span&gt; + i);&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;var&lt;/span&gt; $timeline = genTimeline(9, 21, 800, 30, i == 0);&lt;/pre&gt;&lt;pre&gt;            $tr.find(&lt;span class="str"&gt;&amp;quot;td:last&amp;quot;&lt;/span&gt;).append($timeline);&lt;/pre&gt;&lt;pre class="alt"&gt;            $tbl.append($tr);&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;var&lt;/span&gt; j = 9; j &amp;lt; 21; j++) {&lt;/pre&gt;&lt;pre class="alt"&gt;                $booking = addBooking($timeline, j + &lt;span class="str"&gt;&amp;quot;:00&amp;quot;&lt;/span&gt;, j + &lt;span class="str"&gt;&amp;quot;:30&amp;quot;&lt;/span&gt;, &lt;/pre&gt;&lt;pre&gt;                    &lt;span class="str"&gt;&amp;quot;Test-&amp;quot;&lt;/span&gt; + i + &lt;span class="str"&gt;&amp;quot;-&amp;quot;&lt;/span&gt; + j, &lt;span class="str"&gt;&amp;quot;Test&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;            }&lt;/pre&gt;&lt;pre&gt;        }&lt;/pre&gt;&lt;pre class="alt"&gt;        $(&lt;span class="str"&gt;&amp;quot;body&amp;quot;&lt;/span&gt;).append($tbl);&lt;/pre&gt;&lt;pre&gt;    });&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;style&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text/css&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    .booking&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;        background-color: Green;&lt;/pre&gt;&lt;pre&gt;        color: Yellow;&lt;/pre&gt;&lt;pre class="alt"&gt;    }&lt;/pre&gt;&lt;pre&gt;    div.inverse &lt;/pre&gt;&lt;pre class="alt"&gt;    {&lt;/pre&gt;&lt;pre&gt;        background-color: black;&lt;/pre&gt;&lt;pre class="alt"&gt;        color: White;&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;style&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;【註】只是POC，防呆、檢核及彈性都很薄弱，不足處請自理!&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6045" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/CODE/default.aspx">CODE</category></item><item><title>黑暗jQuery工具包1-動態加入預設Style設定</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/02/25/jquery-tools-addstyles.aspx</link><pubDate>Thu, 25 Feb 2010 06:06:10 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6043</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;對我來說，Javascript在處理CSS上一直有一個小困擾...&lt;/p&gt; &lt;p&gt;一般在習慣上，為了方便開發人員修改，多半會將Style設定獨立放在.css檔案裡，應用者可視需要覆寫或修改之。但有蠻多時候，應用者根本不打算更動CSS內容，只想直接沿用預設CSS設定，但部署時還是少不了要Copy相對應的.css檔案，網頁也必須多加上&amp;lt;style src=&amp;quot;...&amp;quot;&amp;gt;宣告。&lt;/p&gt; &lt;p&gt;我總覺得，最理想的方式是將預設css與js融和在一個檔案裡。當開發者想自行定義CSS樣式，可將其寫在.css中加以引用，或在HTML中以&amp;lt;style&amp;gt;逕行宣告；若只想用預設內容，則只需參照.js就大功告成。&lt;/p&gt; &lt;p&gt;今天遇到類似需求，索性寫了幾個小函數，試著實現上述想法。&lt;/p&gt; &lt;p&gt;我的設計概念是這樣的: 先透過document.styleSheets.cssRules比對某個CSS Selector(例如: div.cCountryPicker)，若已被定義過，表示網頁已透過參照.css檔或直接宣告&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;方式定義了div.cCounterPicker，此時就不需加入預設的div.cCountryPicker樣式規則；反之，若沒有定義該規則，則透過$(&amp;quot;head&amp;quot;).append(&amp;quot;&amp;lt;style type=\&amp;quot;text/css\&amp;quot;&amp;gt;....&amp;quot;)的方式加入Style宣告。&lt;/p&gt; &lt;p&gt;程式碼如下: &lt;br /&gt;(PS: 我規劃用jQuery.Darkthread.*蒐集我陸續開發出來的工具函數，最前面的$.extend用來將多個.js中宣告的jQuery.Darkthread.*函數彙整在一起)&lt;/p&gt; &lt;div class="BlogCodeBlock"&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;/*&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;** Darkthread&amp;#39;s Tools for jQuery ver 1.0 **&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;by Jeffrey, 2010-02-25, http://blog.darkthread.net&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;=======================================================&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;checkStyle: to check if specific style selector is defined&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;addStyles: add &amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt; dynamically&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;addDefaultStyles: if specific style selector isn&amp;#39;t defined, add style setting&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;*/&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;jQuery.extend(jQuery, { Darkthread: {} });&lt;/pre&gt;&lt;pre class="alt"&gt;jQuery.extend(jQuery.Darkthread, {&lt;/pre&gt;&lt;pre&gt;    tools: {&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//ruleSelector sample: a:hover, .myClass, #someId&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        checkStyle:&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;function&lt;/span&gt;(ruleSelector) {&lt;/pre&gt;&lt;pre&gt;            &lt;span class="rem"&gt;//REF: http://www.javascriptkit.com/dhtmltutors/externalcss3.shtml&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;var&lt;/span&gt; cssCol = document.styleSheets;&lt;/pre&gt;&lt;pre&gt;            ruleSelector = ruleSelector.toLowerCase();&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;var&lt;/span&gt; i = 0; i &amp;lt; cssCol.length; i++) {&lt;/pre&gt;&lt;pre&gt;                &lt;span class="kwrd"&gt;var&lt;/span&gt; rules = cssCol[i].cssRules || cssCol[i].rules;&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;for&lt;/span&gt; (j = 0; j &amp;lt; rules.length; j++)&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (rules[j].selectorText.toLowerCase() == ruleSelector)&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;        },&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="rem"&gt;/*styleDictionary sample:&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;        { &lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;        &amp;quot;a:hover&amp;quot;: { &amp;quot;background-color&amp;quot;: &amp;quot;red&amp;quot;, &amp;quot;color&amp;quot;:&amp;quot;yellow&amp;quot; },&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;        &amp;quot;#dvTest&amp;quot;: { &amp;quot;border&amp;quot;, &amp;quot;solid blue 1px&amp;quot; }&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;        }&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;        Note: it&amp;#39;s for &amp;lt;style&amp;gt; declaration, not for jQuery.css, so don&amp;#39;t use &lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;        backgourndColor instead of &amp;quot;background-color&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;        */&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;        addStyles:&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;function&lt;/span&gt;(styleDictionary) {&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;var&lt;/span&gt; sb = [];&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;var&lt;/span&gt; selector &lt;span class="kwrd"&gt;in&lt;/span&gt; styleDictionary) {&lt;/pre&gt;&lt;pre class="alt"&gt;                sb.push(selector + &lt;span class="str"&gt;&amp;quot; {&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;                &lt;span class="kwrd"&gt;var&lt;/span&gt; props = styleDictionary[selector];&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;var&lt;/span&gt; p &lt;span class="kwrd"&gt;in&lt;/span&gt; props) {&lt;/pre&gt;&lt;pre&gt;                    sb.push(p + &lt;span class="str"&gt;&amp;quot;:&amp;quot;&lt;/span&gt; + props[p] + &lt;span class="str"&gt;&amp;quot;;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;                }&lt;/pre&gt;&lt;pre&gt;                sb.push(&lt;span class="str"&gt;&amp;quot;}&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;            }&lt;/pre&gt;&lt;pre&gt;            $(&lt;span class="str"&gt;&amp;quot;head&amp;quot;&lt;/span&gt;).append(&lt;span class="str"&gt;&amp;quot;&amp;lt;style type=\&amp;quot;text/css\&amp;quot;&amp;gt;\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;&lt;pre class="alt"&gt;                sb.join(&lt;span class="str"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;) + &lt;span class="str"&gt;&amp;quot;\n&amp;lt;/style&amp;gt;&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;        },&lt;/pre&gt;&lt;pre class="alt"&gt;        addDefaultStyles:&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;function&lt;/span&gt;(ruleSelector, styleDictionary) {&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (!$.Darkthread.tools.checkStyle(ruleSelector))&lt;/pre&gt;&lt;pre&gt;                $.Darkthread.tools.addStyles(styleDictionary);&lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;});&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;應用方式挺簡單的，將以下的程式寫進.js，等於將預設的.css一起藏進.js裡，就不必再多搞出一個預設用途的.css檔案囉!&lt;/p&gt;
&lt;div class="BlogCodeBlock"&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;    $.Darkthread.tools.addDefaultStyles(&lt;span class="str"&gt;&amp;quot;.dttl_BookingBlock&amp;quot;&lt;/span&gt;, {&lt;/pre&gt;&lt;pre&gt;        &lt;span class="str"&gt;&amp;quot;.dttl_BookingBlock&amp;quot;&lt;/span&gt;: {&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;float&lt;/span&gt;: &lt;span class="str"&gt;&amp;quot;left&amp;quot;&lt;/span&gt;, position: &lt;span class="str"&gt;&amp;quot;absolute&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre&gt;            margin: &lt;span class="str"&gt;&amp;quot;0px&amp;quot;&lt;/span&gt;, padding: &lt;span class="str"&gt;&amp;quot;0px&amp;quot;&lt;/span&gt;, height: &lt;span class="str"&gt;&amp;quot;100%&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="str"&gt;&amp;quot;font-size&amp;quot;&lt;/span&gt;: &lt;span class="str"&gt;&amp;quot;9pt&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;background-color&amp;quot;&lt;/span&gt;: &lt;span class="str"&gt;&amp;quot;#dddddd&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre&gt;            &lt;span class="str"&gt;&amp;quot;border-left&amp;quot;&lt;/span&gt;: &lt;span class="str"&gt;&amp;quot;solid #444444 1px&amp;quot;&lt;/span&gt;,&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="str"&gt;&amp;quot;border-right&amp;quot;&lt;/span&gt;: &lt;span class="str"&gt;&amp;quot;solid #444444 1px&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        },&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;span class="str"&gt;&amp;quot;.ddtl_Timeline&amp;quot;&lt;/span&gt;: { border: &lt;span class="str"&gt;&amp;quot;solid red 1px&amp;quot;&lt;/span&gt; }&lt;/pre&gt;&lt;pre&gt;    });&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;(以上的程式碼，會在網頁本身沒有宣告.dttl_BookingBlock且所有參照的.css中也沒有該宣告時，加入.dttl_BookingBlock及.dttl_Timeline兩條CSS規則，賦與預設Style設定。)&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6043" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/CODE/default.aspx">CODE</category></item><item><title>Outlook 2007無法預覽PDF附件</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/02/23/pdf-preview-error-on-x64.aspx</link><pubDate>Tue, 23 Feb 2010 03:14:51 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6034</guid><dc:creator>Jeffrey</dc:creator><slash:comments>6</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;Outlook 2007在x64平台上無法預覽信件的PDF附件檔，會出現:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font color="#ff8040"&gt;無法預覽此檔案，因為下列預覽器發生錯誤:&lt;br /&gt;PDF Preview Handler for Vista&lt;br /&gt;若要在本身所屬的程式中開啟此檔案，請按兩下檔案。&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;找到&lt;a href="http://www.pretentiousname.com/adobe_pdf_x64_fix/"&gt;這篇文章&lt;/a&gt;，才知道這是Adobe PDF Preview Handler的Bug，網友們已經&lt;a href="http://forums.adobe.com/thread/303008"&gt;抱怨了兩年多&lt;/a&gt;，Adobe還是沒處理，於是該文章的作者就自力救濟寫出修補程式，修改Registry裡錯誤的AppID後，PDF預覽器馬上就可以使用囉~~&lt;/p&gt; &lt;p&gt;PS: 另外，該Fix還做了一個&amp;quot;32/64-bit thumbnail bridge&amp;quot;，一併修正了x64下檔案總管檢視時無法產生PDF內容縮圖的問題(Adobe沒出x64版的縮圖產生器)，真神人也!&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6034" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Trouble-Shooting/default.aspx">Trouble-Shooting</category></item><item><title>升級Win2008R2後Hyper-V VM無法啟動</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/02/22/hyperv-vm-failure-after-r2.aspx</link><pubDate>Mon, 22 Feb 2010 00:27:34 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6024</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;年前將作業系統由Windows 2008&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/02/11/win2008r2.aspx"&gt;升級到Windows 2008 R2&lt;/a&gt;，已有年後要&amp;quot;打地鼠&amp;quot;的心理準備(每日一詞: 【打地鼠】意指針對疑難雜症或系統問題，採取見一個解一個，遇到再說的鄉愿策略)，而今天打了第一隻地鼠...&lt;/p&gt; &lt;p&gt;啟動Hyper-V VM時出現以Microsoft Emulated IDE Controller: Failed to Power on with Error &amp;#39;The system cannot find the file specified.&amp;#39;錯誤，導致VM無法開機。&lt;/p&gt; &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6022/original.aspx" alt="" /&gt;&lt;/p&gt; &lt;p&gt;本以為會很棘手，幸好在檢視VM設定時很快就發現可疑之處: Physical CD/DVD drive:選單出現Drive &amp;#39;Not found&amp;#39;，而下拉選單中另有一筆Drive &amp;#39;D:&amp;#39;應該才是正確的選項。&lt;/p&gt; &lt;p&gt;&lt;img src="http://blog.darkthread.net/photos/darkthread/images/6023/original.aspx" alt="" /&gt;&lt;/p&gt; &lt;p&gt;重設為Driver &amp;#39;D:&amp;#39;後，VM即可順利啟動，而之後再開啟VM Setting，Driver &amp;#39;Not found&amp;#39;選項也消失了，我的推測是升級R2後，DVD光碟機被賦與了新識別碼，而VM設定仍指向舊識別碼，導致上述問題，理論上重新設過就可解決囉。&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6024" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Trouble-Shooting/default.aspx">Trouble-Shooting</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Windows+2008/default.aspx">Windows 2008</category></item><item><title>【茶包射手手札】比蝸牛還慢的HD</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/02/21/ahci-slow-hd.aspx</link><pubDate>Sat, 20 Feb 2010 15:40:09 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6017</guid><dc:creator>Jeffrey</dc:creator><slash:comments>5</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;前一代工作機&lt;a href="http://www.oc.com.tw/readvarticle.asp?id=4316"&gt;XPC SB81P&lt;/a&gt;自從退休後，輾轉流落到客廳，擔任起&amp;quot;偽家電&amp;quot;兼娛樂PC的角色。(老讀者們可能己見過，它在&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/11/29/lcd-tv-seminar.aspx"&gt;這篇文章&lt;/a&gt;中曾露過臉，照片左側音箱上方，巴黎鐵塔下方，我想它能二次就業多少跟黑色鏡面長相脫不了關係，沒想到俊男美女較吃香的定律在硬體界也適用)&lt;/p&gt;  &lt;p&gt;前些時候，周遭的機器接連發生某廠牌HD集體暴斃的慘劇，它也在中鏢之列，便換了顆新硬碟WD 6400AAKS，順便把OS由XP換裝成Windows 7。這台機器我裝完機後幾乎未再碰過，平日多由黑暗女王及兩位王室小成員操作使用。在換HD升OS後，陸續接獲一些抱怨: 放YouTube影片聲音會斷斷續續、某些程式執行過程會停頓一下、跑大型遊戲程式時會當機... &lt;/p&gt;  &lt;p&gt;趁著年假時間較有空，便在客廳扮演一下茶包射手，著手修理這台不乖的電腦。&lt;/p&gt;  &lt;p&gt;實測播放YouTube影片，360p順暢，到480p起就偶有斷續雜音(感覺是CPU跟不上)，720p更是慘不忍睹。有點狐疑，同一台機器，之前裝XP用得還不錯，即便機器老了點(Pentium-D 935 3.2GHz + 2G RAM) ，Windows 7對硬體要求稍高，但直覺上應該不至於連YouTube影片都跑不動。&lt;/p&gt;  &lt;p&gt;Vista/Windows 7起有所謂的&lt;a href="http://windows.microsoft.com/zh-TW/windows-vista/Get-computer-speed-and-performance-information"&gt;效能分數檢測&lt;/a&gt;，是很不錯的初步評量。執行了一次，發現頗意外的結果，這顆新HD居然只有2.7分，是所有分數中最差的。啥? 最新買的裝置居然是整台機器的罩門，太不合理了! &lt;/p&gt;  &lt;p&gt;X光照出異常，接著就該做斷層掃瞄了。找來HD專屬的測速工具--&lt;a href="http://www.hdtune.com/"&gt;HD Tune&lt;/a&gt;，診斷報告一出，我&lt;strike&gt;花容失色&lt;/strike&gt;大吃一驚!!&lt;/p&gt;  &lt;p&gt;&lt;img class="PopBoxImageSmall" src="http://blog.darkthread.net/photos/darkthread/images/6012/500x375.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;嚇! 3MB/s!! 大家評評理，SATA HD都在拼100MB/s的時代，這種速度能看嗎能看嗎?&lt;/p&gt;  &lt;p&gt;&lt;img class="PopBoxImageSmall" src="http://blog.darkthread.net/photos/darkthread/images/6013/500x375.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;經過一番嘗試，發現如果我把BIOS裡的On-Chip Serial ATA Setting/SATA Mode設定由AHCI調回IDE，HD速度就會改善，一舉飆上86MB/s，才是WD 6400AAKS合理的效能表現。&lt;/p&gt;  &lt;p&gt;&lt;img class="PopBoxImageSmall" src="http://blog.darkthread.net/photos/darkthread/images/6011/500x375.aspx" alt="" /&gt;&lt;/p&gt;  &lt;p&gt;為何AHCI模式會導致如此不堪的HD效能數字，噗友&lt;a href="http://www.plurk.com/iwant_neo"&gt;鐵衛在噗浪&lt;/a&gt;提供了一些&lt;a href="http://www.pcdvd.com.tw/showthread.php?t=451161"&gt;情資&lt;/a&gt;，不過似乎於我的狀況不太相同，由HD Tune資訊顯示，HD狀態為UDMA Mode 5。但回想起來，因為XP要換AHCI工程很大，所以AHCI倒真是安裝Windows 7時才調過來的，跟遇到HD效能問題的時點相當，坐實HD問題與AHCI設定有關的推論。&lt;/p&gt;  &lt;p&gt;雖然未知AHCI模式導致HD效能低落的真實原因，但畢竟這是台高壽五年的老機器，若是追到最後，問題出在BIOS卻又不可能再有Update，將情何以堪? 於是我很果斷地決定&amp;quot;面對它、接受它、處理它(調成IDE不就好了)、放下它&amp;quot;，啦啦啦啦~~~ &lt;/p&gt;  &lt;p&gt;在福虎開春之際，茶包射手就用馬馬&lt;strong&gt;&lt;font color="#ff8000"&gt;虎虎&lt;/font&gt;&lt;/strong&gt;的結案態度應景一下(喂!)，順道給大家拜個晚年囉! &lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6017" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Trouble-Shooting/default.aspx">Trouble-Shooting</category></item><item><title>簡易版記憶體用量觀察工具</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/02/17/memwatch.aspx</link><pubDate>Wed, 17 Feb 2010 01:19:49 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6009</guid><dc:creator>Jeffrey</dc:creator><slash:comments>0</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt;  &lt;p&gt;找資料時發現&lt;a href="http://msdn.microsoft.com/zh-tw/library/system.gc.gettotalmemory.aspx"&gt;GC.GetTotalMemory&lt;/a&gt;()這個方法，看到有些人用它來測量記憶體使用狀況，我也好奇玩了一下，包成一個MemWatch Class(比照Stopwatch的概念):&lt;/p&gt;  &lt;div class="BlogCodeBlock"&gt;   &lt;div class="csharpcode"&gt;     &lt;pre class="alt"&gt;&lt;span class="rem"&gt;//簡易版的記憶體用量觀察工具&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="rem"&gt;//  透過觀察Managed Heap的總使用量變化&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="rem"&gt;//  粗略推估某段程式所耗用的記憶體大小 &lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; MemWatch&lt;/pre&gt;

    &lt;pre class="alt"&gt;{&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="rem"&gt;//比較記憶體使用量變化的基準值&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;long&lt;/span&gt; _lastTotalMemory = 0;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="rem"&gt;//記憶體使用量變化&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;long&lt;/span&gt; MemorySizeChange = 0;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="rem"&gt;//是否強制GC再測量記憶體用量&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; _forceGC = &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="rem"&gt;//可指定測量前是否要先做GC&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="rem"&gt;//(可排除己不用但尚未回收的記憶體)&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; MemWatch(&lt;span class="kwrd"&gt;bool&lt;/span&gt; forceGC)&lt;/pre&gt;

    &lt;pre class="alt"&gt;    {&lt;/pre&gt;

    &lt;pre&gt;        _forceGC = forceGC;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    }&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; MemWatch() : &lt;span class="kwrd"&gt;this&lt;/span&gt;(&lt;span class="kwrd"&gt;false&lt;/span&gt;) { }&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="rem"&gt;//保留測量開始之基準&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Start()&lt;/pre&gt;

    &lt;pre class="alt"&gt;    {&lt;/pre&gt;

    &lt;pre&gt;        _lastTotalMemory = &lt;/pre&gt;

    &lt;pre class="alt"&gt;            GC.GetTotalMemory(_forceGC);&lt;/pre&gt;

    &lt;pre&gt;    }&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="rem"&gt;//測量從Start()至今的記憶體變化&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Stop()&lt;/pre&gt;

    &lt;pre class="alt"&gt;    {&lt;/pre&gt;

    &lt;pre&gt;        MemorySizeChange =&lt;/pre&gt;

    &lt;pre class="alt"&gt;             GC.GetTotalMemory(_forceGC) - _lastTotalMemory;&lt;/pre&gt;

    &lt;pre&gt;    }&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="rem"&gt;//記憶體使用量變化(以KB計)&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; MemorySizeChangeInKB&lt;/pre&gt;

    &lt;pre class="alt"&gt;    {&lt;/pre&gt;

    &lt;pre&gt;        get&lt;/pre&gt;

    &lt;pre class="alt"&gt;        {&lt;/pre&gt;

    &lt;pre&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;&amp;quot;{0:N0}KB&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

    &lt;pre class="alt"&gt;                MemorySizeChange / 1024);&lt;/pre&gt;

    &lt;pre&gt;        }&lt;/pre&gt;

    &lt;pre class="alt"&gt;    }&lt;/pre&gt;

    &lt;pre&gt;    &lt;span class="rem"&gt;//記憶體使用量變化(以MB計)&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; MemorySizeChangeInMB&lt;/pre&gt;

    &lt;pre&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        get&lt;/pre&gt;

    &lt;pre&gt;        {&lt;/pre&gt;

    &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;&amp;quot;{0:N0}MB&amp;quot;&lt;/span&gt;, &lt;/pre&gt;

    &lt;pre&gt;                MemorySizeChange / 1024 / 1024);&lt;/pre&gt;

    &lt;pre class="alt"&gt;        }&lt;/pre&gt;

    &lt;pre&gt;    }&lt;/pre&gt;

    &lt;pre class="alt"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;測試時，故意宣告指定大小的byte[]，看看結果是否如預期:&lt;/p&gt;

&lt;div class="BlogCodeBlock"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; Program&lt;/pre&gt;

    &lt;pre&gt;{&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;

    &lt;pre&gt;    {&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//測試1-宣告byte陣列記憶體使用&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="rem"&gt;//利用MemWatch觀察Heap記憶體使用狀況&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        MemWatch mw = &lt;span class="kwrd"&gt;new&lt;/span&gt; MemWatch();&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="rem"&gt;//宣告前先記錄使用前的記憶體用量&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        mw.Start();&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] b1 = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;[512 * 1024];&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//宣告後再測一次&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        mw.Stop();&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//會得到二次的記體變化差距為512KB&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        Console.WriteLine(mw.MemorySizeChangeInKB);&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="rem"&gt;//測試2-這次宣告byte陣列後立即棄用，但不做GC&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        mw.Start();&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] b2 = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;[256 * 1024];&lt;/pre&gt;

    &lt;pre class="alt"&gt;        b2 = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;        mw.Stop();&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//b2佔用記憶體已釋出，但尚未回收，結果為256KB&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        Console.WriteLine(mw.MemorySizeChangeInKB);&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="rem"&gt;//進行下一階段測試前先強制GC&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        GC.Collect();&lt;/pre&gt;

    &lt;pre&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//測試3-同2，但換成先GC才測記憶體大小的測量模式&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        mw = &lt;span class="kwrd"&gt;new&lt;/span&gt; MemWatch(&lt;span class="kwrd"&gt;true&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre class="alt"&gt;        mw.Start();&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] b3 = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;byte&lt;/span&gt;[256 * 1024];&lt;/pre&gt;

    &lt;pre class="alt"&gt;        b3 = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;

    &lt;pre&gt;        mw.Stop();&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="rem"&gt;//MemWatch測量時會先將b2釋出的記憶體回收，故結果為0KB&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;        Console.WriteLine(mw.MemorySizeChangeInKB);&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;        Console.Read();&lt;/pre&gt;

    &lt;pre class="alt"&gt;    }&lt;/pre&gt;

    &lt;pre&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;補充:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;GC.GetTotalMemory()只能取得Managed Heap部分的大小，若變數耗用的是Stack部分的記憶體(例如: &lt;a href="http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory01122006130034PM/csharp_memory.ASPx"&gt;Value Type&lt;/a&gt;)，則不在量測範圍內。 &lt;/li&gt;

  &lt;li&gt;GetTotalMemeory()只能量測總耗用量，無法精準指出特定變數/物件所耗用記憶體大小。 &lt;/li&gt;

  &lt;li&gt;MemWatch預設會包含配置後棄用但尚未被GC機制回收的記憶體量，若要強制回收可自行呼叫GC.Collect()或用MemWatch(true)建構式啟用強制回收模式。&lt;font color="#ff8000"&gt;注意，這裡是因測試需要才自行操作GC回收，實務上應避免在程式中自行呼叫GC.Collect()，最好交由.NET Runtime自行決定何時進行回收，較有利於整體效能。 &lt;/font&gt;&lt;/li&gt;

  &lt;li&gt;Compiler常會針對程式碼進行最佳化(例如: 忽略只宣告但完全未使用的物件、改變程式執行順序以改善效率...等等)，因此當執行結果與預期出入很大時，可研究看看是否與最佳化有關。 &lt;/li&gt;
&lt;/ol&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6009" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/.NET/default.aspx">.NET</category></item><item><title>升級Windows 2008 R2!!</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/02/11/win2008r2.aspx</link><pubDate>Thu, 11 Feb 2010 01:48:09 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6005</guid><dc:creator>Jeffrey</dc:creator><slash:comments>5</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;Windows 2008 R2已上市好一段時日，我現在工作桌機的OS是Windows 2008 x64(翻了一下日記，是&lt;a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/10/06/burn-dvd-under-windows-2008-x64.aspx"&gt;一年多前&lt;/a&gt;裝的)，雖然蠻想升級R2嘗鮮，但礙於更換OS茲事體大，若安裝升級過程發生不測，重新安裝/還原工作環境工程浩大，手上工作就都得停擺了。&lt;/p&gt; &lt;p&gt;趁著有一星期年假可以做為緩衝，前陣子我就偷偷策劃，打算趁過年把OS升級到R2，一併除舊佈新一番。過去升級OS我都是重新安裝再搬檔案，砍掉重練感覺比較乾淨俐落。但這回想偷懶，決定第一次試試&amp;quot;就地升級&amp;quot;的OS安裝法。&lt;/p&gt; &lt;p&gt;昨天部門吃尾牙，出發前我啟動了安裝程式(注意: 要&lt;a href="http://support.microsoft.com/kb/957256/en-us"&gt;先將所有Hyper-V VM Shutdown&lt;/a&gt;)，接著下一步下一步地進入升級程序(畫面上還很貼心地提供了進度跟處理檔案數)，不打算坐在電腦前枯等，就開開心心吃尾牙去~~&lt;/p&gt; &lt;p&gt;&lt;img class="PopBoxImageSmall" src="http://blog.darkthread.net/photos/darkthread/images/6003/500x375.aspx" alt="" /&gt;&lt;/p&gt; &lt;p&gt;尾牙結束回到辦公室，電腦已裝好重開完畢，等待我登入的已經是Windows 2008 R2 x64了，登入後系統環境大致如常，真是讓人愉悅的安裝經驗呀!!&lt;/p&gt; &lt;p&gt;&lt;img class="PopBoxImageSmall" src="http://blog.darkthread.net/photos/darkthread/images/6004/500x375.aspx" alt="" /&gt;&lt;/p&gt; &lt;p&gt;今天小小實地用了一下，微調了幾個小地方: &lt;/p&gt; &lt;ol&gt; &lt;li&gt;IE8會復原成原始設定(但我的最愛會保留)，首頁設定、Cookie等也會被清除  &lt;li&gt;預設沒有聲音，要先Enable Audio Service  &lt;li&gt;發現不能使用Windows 7 Aero Theme，爬了文發現是因為Theme Service被Disabled的原因。  &lt;li&gt;我還是很習慣在工作列直接點小圖示啟動程式，所以花了點功夫&lt;a href="http://www.howtogeek.com/howto/windows-7/add-the-quick-launch-bar-to-the-taskbar-in-windows-7/"&gt;Add Quick Launch Toolbar&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;感覺上原來的工作環境已完整被搬來R2，其他問題就等遇到再用打地鼠法解決吧!&lt;/p&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6005" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/Windows+2008/default.aspx">Windows 2008</category></item><item><title>CODE-Convert Text to PDF in C#</title><link>http://blog.darkthread.net/blogs/darkthreadtw/archive/2010/02/09/text-to-pdf.aspx</link><pubDate>Tue, 09 Feb 2010 05:12:49 GMT</pubDate><guid isPermaLink="false">d08a49d6-af59-4068-8b43-b7c037f78068:6000</guid><dc:creator>Jeffrey</dc:creator><slash:comments>2</slash:comments><description>&lt;span id="PostName"&gt;&lt;/span&gt; &lt;p&gt;透過程式直接將Text內容轉換成PDF的程式範例，寫來給其他組同事做為系統整合模組開發參考，順便PO文備忘。&lt;/p&gt; &lt;p&gt;要在.NET轉PDF，當然少不了大家都說讚的&lt;a href="http://itextsharp.sourceforge.net/"&gt;iTextSharp&lt;/a&gt;，程式很簡單，我還順手加了一個遇到&amp;quot;\f&amp;quot; (0x0C) Form Feed符號就強制換新頁的功能。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="BlogCodeBlock"&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="asp"&gt;&amp;lt;%@ Page Language=&amp;quot;C#&amp;quot; %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="asp"&gt;&amp;lt;%@ Import Namespace=&amp;quot;iTextSharp.text&amp;quot; %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="asp"&gt;&amp;lt;%@ Import Namespace=&amp;quot;iTextSharp.text.pdf&amp;quot; %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="asp"&gt;&amp;lt;%@ Import Namespace=&amp;quot;System.IO&amp;quot; %&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; btnConvert_Click(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;&lt;pre&gt;    {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;//REF: http://www.codeproject.com/KB/graphics/iTextSharpTutorial.aspx&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;        Document doc = &lt;span class="kwrd"&gt;new&lt;/span&gt; Document(PageSize.A4.Rotate());&lt;/pre&gt;&lt;pre class="alt"&gt;        &lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;using&lt;/span&gt; (MemoryStream ms = &lt;span class="kwrd"&gt;new&lt;/span&gt; MemoryStream())&lt;/pre&gt;&lt;pre class="alt"&gt;        {&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class="alt"&gt;                PdfWriter.GetInstance(doc, ms);&lt;/pre&gt;&lt;pre&gt;                doc.Open();&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="rem"&gt;//中文字型問題REF &lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="rem"&gt;//http://renjin.blogspot.com/2009/01/using-chinese-fonts-in-itextsharp.html&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;string&lt;/span&gt; fontPath = &lt;/pre&gt;&lt;pre&gt;                    Environment.GetFolderPath(&lt;/pre&gt;&lt;pre class="alt"&gt;                    Environment.SpecialFolder.System) +&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="str"&gt;@&amp;quot;\..\Fonts\kaiu.ttf&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt;                BaseFont bfChinese = BaseFont.CreateFont(&lt;/pre&gt;&lt;pre&gt;                    fontPath,&lt;/pre&gt;&lt;pre class="alt"&gt;                    BaseFont.IDENTITY_H, &lt;span class="rem"&gt;//橫式中文&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;                    BaseFont.NOT_EMBEDDED&lt;/pre&gt;&lt;pre class="alt"&gt;                );&lt;/pre&gt;&lt;pre&gt;                Font fontChinese = &lt;span class="kwrd"&gt;new&lt;/span&gt; Font(bfChinese, 8f, Font.NORMAL);&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;/pre&gt;&lt;pre&gt;                StringReader sr = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringReader(txtInput.Text);&lt;/pre&gt;&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;string&lt;/span&gt; line = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;                &lt;span class="kwrd"&gt;while&lt;/span&gt; ((line = sr.ReadLine()) != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;                {&lt;/pre&gt;&lt;pre&gt;                    &lt;span class="kwrd"&gt;string&lt;/span&gt;[] p = line.Split(&lt;span class="str"&gt;&amp;#39;\f&amp;#39;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt; s &lt;span class="kwrd"&gt;in&lt;/span&gt; p)&lt;/pre&gt;&lt;pre&gt;                    {&lt;/pre&gt;&lt;pre class="alt"&gt;                        doc.Add(&lt;span class="kwrd"&gt;new&lt;/span&gt; Paragraph(s, fontChinese));&lt;/pre&gt;&lt;pre&gt;                        &lt;span class="kwrd"&gt;if&lt;/span&gt; (p.Length &amp;gt; 1) &lt;span class="rem"&gt;//表示有換頁符號&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;                            doc.NewPage();&lt;/pre&gt;&lt;pre&gt;                    }&lt;/pre&gt;&lt;pre class="alt"&gt;                }&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;catch&lt;/span&gt; (DocumentException de)&lt;/pre&gt;&lt;pre&gt;            {&lt;/pre&gt;&lt;pre class="alt"&gt;                Response.Write(de.Message);&lt;/pre&gt;&lt;pre&gt;                Response.End();&lt;/pre&gt;&lt;pre class="alt"&gt;            }&lt;/pre&gt;&lt;pre&gt;            &lt;span class="kwrd"&gt;catch&lt;/span&gt; (IOException ioe)&lt;/pre&gt;&lt;pre class="alt"&gt;            {&lt;/pre&gt;&lt;pre&gt;                Response.Write(ioe.Message);&lt;/pre&gt;&lt;pre class="alt"&gt;                Response.End();&lt;/pre&gt;&lt;pre&gt;            }&lt;/pre&gt;&lt;pre class="alt"&gt;            doc.Close();&lt;/pre&gt;&lt;pre&gt;            &lt;span class="rem"&gt;//Output PDF&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;            Response.Clear();&lt;/pre&gt;&lt;pre&gt;            Response.ContentType = &lt;span class="str"&gt;&amp;quot;application/octet-stream&amp;quot;&lt;/span&gt;;&lt;/pre&gt;&lt;pre class="alt"&gt;            Response.AddHeader(&lt;span class="str"&gt;&amp;quot;content-disposition&amp;quot;&lt;/span&gt;, &lt;/pre&gt;&lt;pre&gt;                &lt;span class="str"&gt;&amp;quot;attachment;filename=output.pdf&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;pre class="alt"&gt;            Response.BinaryWrite(ms.ToArray());&lt;/pre&gt;&lt;pre&gt;            Response.End();&lt;/pre&gt;&lt;pre class="alt"&gt;        }&lt;/pre&gt;&lt;pre&gt;                    &lt;/pre&gt;&lt;pre class="alt"&gt;    }&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;head&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;title&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Text to PDF demo&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;title&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;head&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;form1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:TextBox&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;txtInput&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Height&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;600px&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;TextMode&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;MultiLine&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;pre&gt;            &lt;span class="attr"&gt;Width&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;800px&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;asp:TextBox&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;br&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:Button&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;btnConvert&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;onclick&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;btnConvert_Click&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;pre&gt;            &lt;span class="attr"&gt;Text&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Convert to PDF&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;div&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;img src="http://blog.darkthread.net/aggbug.aspx?PostID=6000" width="1" height="1"&gt;</description><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/.NET/default.aspx">.NET</category><category domain="http://blog.darkthread.net/blogs/darkthreadtw/archive/tags/CODE/default.aspx">CODE</category></item></channel></rss>