星期三, 12月 30, 2009

餐廳列表

每次想吃什麼都想不到
事後想起才覺得可惜 忘了這間
先寫好 以便日後查詢...改名叫"魚乾的美食筆記本"好了

台北
墨西哥料理

佬墨日出-Tequila Sunrise
墨西哥餐飲美味道地,經典的仙格麗亞,順口的瑪格麗特,香脆玉米片搭配勁辣爽口瀟灑醬


義大利麵

La Pasta

中式熱炒
新東南活海鮮料理
鮮納肚~100元快炒店(東區)

星期三, 12月 16, 2009

Facebook 二三事

FBML
json_encode問題~ php有些版本不支援
但只要引用facebook.php 就會有了
require_once 'facebook.php';

FBJS
當只有script時,一定要有個內文,script才會執行
echo "test
<script> function go(){
//xxx
}
go();
</script>";


showPermissionDialog說有ondone,但加了會掛...拿掉反而可以執行..怪
Facebook.showPermissionDialog('publish_stream');

星期一, 12月 07, 2009

Refactoring: Impoving The Design of Existing Code

中譯:重構-改善既有程式的設計

前言

古老的工程諺語:「如果它還能執行,就不要動它」
 但專案功能不斷修改程碼,使原先系統結構逐漸衺弱,程式碼也更加複雜,無法除錯,也無法獲得可被接受的性能/效率
最後重新編寫整個系統,作者指出堅持以持續不斷的重構行為是成功專案的重要角色

重構:「在不改變程式碼外在行為的前提下,對程式碼做出修改,以改進程式的內部結構」

軟體會慢慢腐爛
 重構的步驟只要把某欄位(field)從一個class移到另一個class,把某段程式碼從method拉出成另一個method,或是在class hierarchy中把某些程式碼推上推下就行了,聚沙成塔,小小的修改累積就可以改善設計品質,這和「軟體會慢慢腐爛」的觀點恰恰相反

Ch1 Refactoring, a First Example

分解並重組method
案例中的錄影帶出租statement()做太多事,程式碼太長,可以其目的拆成至不同的class
每個method的程式碼越少越容易維護,且拆成 更多的method更容易reuse(copy-paste相同的程式碼,常發生改了a method忘了改相同容內的b method)
重構技術係以微小的步伐修改程式。改錯時,很容易發現它

更改變數是值得的行為嗎?(p.15)
好的程式碼應清楚表達自己的功能,變數名稱是程式碼清晰的關鍵
任何一個傻瓜都能寫出計算機可以理解的程式碼。唯有寫出人類容易理解的程式碼,才是優秀的程式員


Replace Temp with Query(p.21)
int thisAmount => each.getCharge()
儘量除去暫時變數,暫時變數會導致大量參數被傳來傳去。也很容易失去蹤跡=>相對要付出效率上的代價,但可由最佳化來調整(細節p.69)

運用多型取代與價格相關的條件邏輯(p.34)
=>引用State pattern
在父類別宣告abstract int getPriceCode(),讓子類別實作其條件,使其有自己的計費法
*另外邏輯判斷也該在物件本身的class(指switch(getMovie().getPriceCode())=>應在class movie裡寫switch (getPriceCode())
當有傳入值有可能有變化時,選擇可能變化小的,折起的side effect也較小
=>引用State pattern的重點在「修改與價格有關的行為」,或「新增定價標準」會較容易

Ch2 Principles in Refactoring

為何重構
-改進軟體設計=>消除duplicate code
-使軟體更易被理解
-助找到bugs=>程式碼易於理解,而不是從一個500行的method找

何時重構 The Rule of Three (p.58)
1.反感,第三次又做類似的事就該重構
2.添加功能時
3.修補錯誤時
4.code review時

Ch3 Bad smells in Code

何時重構、何時停止及重構的機制
1.Duplicated Code p.76
2.Long Method p.76
3.Large Class p.78
class太大,instance變數就會多,Duplicated Code也接腫而至
4.Long Parameter List p.78
5.Divergent Change(發散式變化) p.79
隨外界變化而有所修改,找出原因運幅Extract Clss提煉到另一個class
6.Shotgun Surgery(霰彈式修改) p.80
每遇修改就得在不同的classes內做小修改
7.Feature Envy(依戀情結)
某method內呼叫該class幾乎半打的getting method
8.Data Clumps
每次都會同時出現的幾個field
9.Primitive Obsession
日期年月日,3個int不如定義成object
原則
應放在一起的fields =>Extract Class
參數列中有基本型資料=>Introduce Parameter Object
從array挑資料 =>Replace Array with Object
10.Switch Statements

星期五, 11月 27, 2009

軟體工程

物件導向

物件導向程式的九個體操練習
by ihower
遵守九條規則,改善OO實作能力

測試
為什麼要寫 unit test?為什麼要先寫測試?
TDD 推廣:背景知識和簡介

看來還有很多東西要學習...加油...

星期四, 11月 26, 2009

INF檔結構

INF是Device INFormation File的英文縮寫

編寫規則

*規則一:INF文件是分節的,每一個INF文件有許多的節組成,節名用方括號括起來。
*規則二:在節與節之間的內容叫條目,每一個節又是由許多的條目組成的,每一個條目都是由形如「signature="$CHICAGO$"」的形式組成的。如果每一個條目的等號後有多個值,則每一個值之間用「,」號分隔開。
  
*規則三:INF文件對大小寫不敏感。  
*規則四:「;」號後面的內容為註釋。
*規則五:如果一個條目的內容過多,在一行無法書寫完全,則用「\」將一行內容書寫為多行。

百度Inf

星期日, 11月 22, 2009

資料庫索引

設計準則(減少IO存取次數)
 1.經常被用來搜尋資料記錄的欄位
 2.Primary key(sqlserver自動建立)
 3.套用unique限制條件的欄位(sqlserver自動建立)
 4.Foreign key定義作為外部索引鍵欄位?
 5.於查詢中被用來連結資料表的欄位
 6.用來作排序基準的欄位
  -不要替超過20bytes的欄位作索引(索引體佔太多空間 ex.地址)
  -很少變動,經幣被查詢
 7.索引需維設,減少使用頻率低的索引,以免耗維護成本
 8.內容重複率高的欄位效益低
 9.資料記錄多,存取效率才會明顯,反過來說少反而慢(path)
  -利用query analyzer執行,檢視execution plan與執行時間來測
  -不斷嚐試、不停修正

索引的類型
 1.Clustered Index(簇集索引) -範圍(日期,編號)
 改變資料表記錄存放次序,並與簇集索引中錄值次序相同
  -ex. between 100 and 200=>以昇冪來排就直接抓出其間的100筆
  每個table只能有一個clustered index

 2.NonClustered index(非簇集索引) -特定值(姓名,電話)

星期五, 10月 30, 2009

要先引用幾個COM元件
查了一下還真麻煩
後來發現直接引進Microsoft Excel 11 Object就會自動帶入其他的COM

[C# .Net] Microsoft.Office.Interop.Excel 讀 / 寫 Excel 語法概全

Reading and Writing Excel Spreadsheets Using ADO.NET C# DbProviderFactory

星期一, 10月 19, 2009

jQuery bind與live

要加event listener時,可用bind或live來綁event 究竟兩者差在哪邊 bind如下以綁drag事件
$(function(){
   $('.floatBox').bind('drag',function( event ){
       $( this ).css({
                       top: event.offsetY,
                       left: event.offsetX
       });
       //var pageCoords = "( " + e.pageX + ", " + e.pageY + " )";
       //var clientCoords = "( " + e.clientX + ", " + e.clientY + " )";
   }); 
});
將event在onload時,加入listener 可是當之後要動態加入時,後續加入的floatBox就不會有反應 因此得再bind的新的floatBox 這時就可以改用live,程式碼如下(只是把bind改用live) jQuery就會聰明的自己bind事件,真的是太神奇了
$(function(){
   $('.floatBox').live('drag',function( event ){
       $( this ).css({
                       top: event.offsetY,
                       left: event.offsetX
       });      
   }); 
});

不規則 Form 透背及拖曳

簡單方法 (只限24bit color以下)
//將form的透明鍵值設為一特定值
//方法1.圖中的10,10為透明鍵值
this.TransparencyKey = Img.GetPixel(10,10);

//方法2.直接指定顏色為透明鍵值
this.TransparencyKey = System.Drawing.Color.Transparent;//指定透明色
this.TransparencyKey = Color.Red; //或指定特定色

如此一來 圖中有該指定色 即會透明

如果放在panel裡,那panel也要設透背
在panel要設背景色,才會透到form上的顏色(當然...form也是透背...)
xxPanel.BackColor = System.Drawing.Color.Transparent;
這樣裡面的東西才會透背

WebBrowser透背
只要在form的屬性設TransparencyKey 為Transparent即可
剩下的當然是網頁裡的圖要去背

另一種方法-以圖去畫透背 ( 24bit Color 以上適用 )
先引用using System.Drawing.Drawing2D;
看source吧



--

假設標題列(pnlTitle)為拖曳
//全域變數
int nOldWndLeft;
int nOldWndTop;
int nClickX;
int nClickY;
...

#region "GUI event"
//滑鼠按下的事件
private void pnlTitle_MouseDown(object sender, MouseEventArgs e)
{
nOldWndLeft = this.Left;
nOldWndTop = this.Top;
nClickX = e.X;
nClickY = e.Y;
}

//滑鼠拖曳事件
private void pnlTitle_MouseMove(object sender, MouseEventArgs e)
{
if (pnlTitle.Capture == true) //如果滑鼠按著拖曳
{
//'設定新的視窗位置
this.Top = e.Y + nOldWndTop - nClickY;
this.Left = e.X + nOldWndLeft - nClickX;
//更新紀錄的視窗位置
nOldWndLeft = this.Left;
nOldWndTop = this.Top;
}
}
#endregion



form在拖拉時會產生閃爍問題
//建構子裡
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
SetStyle(ControlStyles.DoubleBuffer, true); // 雙緩衝


source:
C#製作不規則窗口 ( 24bit Color 以上適用 )

星期五, 10月 16, 2009

facebook DataStoreAdmin怎麼搞

利用facebook的object data要來存資料
什麼type,又property看了半天都看不懂
努力查資料加亂測總算試出來了
如果把object data看成database(object)

A.建立Table
相關API: Object Data Definition API
1.Object Type:就是table(class) 原文:object type is like a "table" in SQL terminology, or a "class" in object-oriented programming concept
2.Object Properties:就是DB中的Column(或物件中屬性)

B.新增、刪除、修改資料
相關API:Object Data AccessAPI
想說總算會依樣畫葫蘆了
本能反應的用FQL來insert... 居然失敗了...
又花了點時間才發知道不是這簡單...

1.新增
搞了好久... 原來要create...
所以還是別以talbe的觀念來做 不然要想好久..
不過create完...讓我在想是只存在記憶體...重開就沒了嗎
$result=api_client->data_createObject("tablename",array('name'=>123,'tel'='123456')); //回傳即$obj_id
2.修改
api_client->data_updateObject($obj_id,$properties,$replace)

利用DataStoreAdmin來建立table
建了半天也建不出來,才發現只能用小寫,
有大寫字也沒說失敗 就改半天不知是怎樣
而且改成功沒有新增的或修改過的名稱不會馬上出現
要refresh過才會有

星期四, 10月 15, 2009

CSS去除連結虛線框,無法用輸入法,刪除,貼上

鏈結在focus後,會出現鏈結虛線


為了去除連結虛線框,會在CSS下以下語法
//css
a, input{
outline: none; /* for Firefox */
hlbr:expression(this.onFocus=this.blur()); /* for IE */
}


但利會造成輸入方塊(input type='text'),無法用輸入法、刪除、貼上
因為foucs就blur,所以無法鎖住在textbox上
就依樣畫葫蘆吧... 在textbox下void(0)...
//html
<input type="text" style="hlbr:expression(void(0));">

星期一, 9月 28, 2009

html做listbox單選

html做listbox很簡單,就select tag加個multiple屬性為true即可
但都mutiple了怎麼做單選... 好像在找碴
上網查一下 好像沒人做這麼無聊的事
但美工很機車... 只好自己來了 (johnny我恨你)
利用javascript動態讀一下

html
<select id="test1" multiple="true"> //設multiple為true
 //<option id='test1_opt1'>1</option>
 ...
 //就不多寫了,不過得先為option取可識別的名字
</select>


javascript ... 唔 其實是透過jquery
var lastSelectedID=-1;
$("select#test1").change(function(){
 var tmpLastSelectedID=-1;
 jQuery('option:selected', this).each(function(){
  //避開滑鼠直接選2個以上
  if(tmpLastSelectedID>0){
   $(this).attr("selected",false);
   return true;
  }

  //避開ctrl點選
  if (lastSelectedID==$(this).attr("id")){
   $(this).attr("selected",false);
   return true;
  }else{
   tmpLastSelectedID=id;
  }
 });
 lastSelectedID=tmpLastSelectedID;
});


p.s 不過避開滑鼠直接選2個以上還有問題 就是都是預設選到第一個

星期五, 9月 25, 2009

即刻提升jQuery性能的十个技巧[TUTS+]

1. 使用最新版本
2. 合併、最小化腳本
3. 用for替代each
4. 用ID替代class選擇器
5. 給選擇器指定前後文
6. 建立緩存
7. 避免DOM操作
8. 避免使用concat(),利用join()處理長字串
9. 返回false值
10. 利用小抄和參考文檔



英文 NetTut+:10 Ways to Instantly Increase Your jQuery Performance
中文翻譯:十种方式即刻提升您的jQuery代码性能[TUTS+]

星期二, 9月 22, 2009

jqgrid 3.5 需配合jquery ui

website:http://www.trirand.com/blog/
document: wiki jqgrid 趕流行,3.5後也利用wiki編文件了
download: jqgrid lastest

正要寫個新專案要用到jqGrid
看到jqGrid 3.5釋出了 就開心的拿來用
下載時發現 還「金熬」跟jquery ui一樣可自定要的功能再下載


青菜勾勾就按了下載...
解開壓縮檔 看到有install.txt
看都不看 照著過去的方法 就去設定了

結果搞了半天還沒出來
記得兩、三下就該用好的東西呀
還上網查了一下... 結果查到自己寫的設定 = ="
怪了... 最後認命的再打開install.txt看
才知道設定有改了,但是demo的內文還是用舊的
所以不能開心的全複製貼上...要小調一下

1.不用自定的theme,改用jquery-ui
download: jquery-ui
問:什麼..鏈結只是網站...
答:自己勾要載什麼啦 啥... 不知要勾什麼...這...問goolge大神吧
所以囉,要再html裡加入這句
<link rel="stylesheet" type="text/css" media="screen" href="path_to_ui_css_file/jquery-ui-1.7.2.custom.css" />

2.指定jqgrid.css
雖然改用了jquery-ui,但本身還是有其css設定
<link rel="stylesheet" type="text/css" media="screen" href="path_to_jqgrid_css_file/ui.jqgrid.css" />

3.指定grid.locale-XX.js及jquery.jqGrid.min.js
grid.locale-XX.js是語系包,在js/i18n的資料夾裡
jquery.jqGrid.min.js當然就是jgGrid本身的js啦
<script src="path_to_js_files/grid.locale-en.js" type="text/javascript"/></script/>
<script src="path_to_js_files/jquery.jqGrid.min.js" type="text/javascript"/></script/>


而原本設定的"imgpath"就用不到了
jQuery("#list4").jqGrid(
...
imgpath: gridimgpath //這行就不用了,拿掉
});


完整的範例如下 (利用array完成)
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <script src="js/jquery-1.3.2.min.js" type="text/javascript"></script>
    <script src="js/i18n/grid.locale-en.js" type="text/javascript"></script>
    <script src="js/jquery.jqGrid.min.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" media="screen" href="css/ui-lightness/jquery-ui-1.7.2.custom.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="css/ui.jqgrid.css" />

<script type="text/javascript">
$(function(){ 
    jQuery("#list4").jqGrid({
        datatype: "local",
        height: 250,
        colNames: ['Inv No', 'Date', 'Client', 'Amount', 'Tax', 'Total', 'Notes'],
        colModel: [
            {
                name: 'id',
                index: 'id',
                width: 60,
                sorttype: "int"
            }, {
                name: 'invdate',
                index: 'invdate',
                width: 90,
                sorttype: "date"
            }, {
                name: 'name',
                index: 'name',
                width: 100
            }, {
                name: 'amount',
                index: 'amount',
                width: 80,
                align: "right",
                sorttype: "float"
            }, {
                name: 'tax',
                index: 'tax',
                width: 80,
                align: "right",
                sorttype: "float"
            }, {
                name: 'total',
                index: 'total',
                width: 80,
                align: "right",
                sorttype: "float"
            }, {
                name: 'note',
                index: 'note',
                width: 150,
                sortable: false
            }],
                multiselect: true,
                caption: "Manipulating Array Data"
        });
    var mydata = [{
        id: "1",
        invdate: "2007-10-01",
        name: "test",
        note: "note",
        amount: "200.00",
        tax: "10.00",
        total: "210.00"
    }, {
        id: "2",
        invdate: "2007-10-03",
        name: "test2",
        note: "note2",
        amount: "300.00",
        tax: "20.00",
        total: "320.00"
    }, {
        id: "3",
        invdate: "2007-09-01",
        name: "test3",
        note: "note3",
        amount: "400.00",
        tax: "30.00",
        total: "430.00"
    }];
    for (var i = 0; i <= mydata.length; i++) 
        jQuery("#list4").addRowData(i + 1, mydata[i]);
    });
</script>
</head>
<body>
    <table id="list4" class="scroll" cellpadding="0" cellspacing="0">
</table>
</body>
</html>

星期四, 9月 17, 2009

jquery autocomplete ie 無效

新的網頁需要autocomplete的效果
用了半天卻用不出來
看看過去用的 程式碼一模一樣也沒用

不過在firefox就很開心的出現
ie就掛在那邊

一個個測試下才發現是
美工為了去除連結虛線框
在css裡加了以下這段
a,input {
outline: none; /* for Firefox */
hlbr:expression(this.onFocus=this.blur()); /* for IE */
}


這就難怪了
autocomplete就是在input被focus時才會出現
而這css在focus時 馬上就blur... 難怪沒出現

星期二, 9月 15, 2009

帳號、密碼的管理

存放帳、密
利用windows的註冊表來儲放帳、密

//在註冊表的HKEY_CURRENT_USER下建立AccountInfo資料夾及kevyu的鍵值
using Microsoft.Win32;
...
RegistryKey key = Registry.CurrentUser; //放在CurrentUser下
RegistryKey newkey = key.CreateSubKey(@"AccountInfo"); //在CurrentUser下建立AccountInfo資料夾
newkey.SetValue("kevyu", "ok1234"); //建立kevyu的密碼值 ok1234

//讀取值
RegistryKey mykey = key.OpenSubKey(@"AccountInfo", true);
Console.WriteLine("kevyu's password is " + mykey.GetValue("kevyu"));

當然 這樣存明碼實在太high了...
看下一步來加密

加密
存儲密碼——要做對

星期一, 9月 14, 2009

jQuery 套件 - 廣告輪播跑馬燈

網址:jQuery Cycle Plugin
效果不錯,而且範例的圖片及jquery core都是用網路鏈結
載回去就可以直接跑了 都不用更改路徑
就感心ㄟ
See More Demos and Examples

* Super Basic Demo (view source for details)
* Beginner Demos
* Intermediate Demos (Part 1)
* Intermediate Demos (Part 2)
* Advanced Demos (Part 1)
* Advanced Demos (Part 2)
* Even More Demos (lots of additinal demos can be found here)

<!-- 設定輪播框架外觀 -->
<style type="text/css">
.slideshow { height: 232px; width: 232px; }
.slideshow img { padding: 15px; border: 1px solid #ccc; background-color: #eee; }
</style>
<!-- include jQuery library -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<!-- include Cycle plugin -->
<script type="text/javascript" src="http://jquery.malsup.com/cycle/jquery.cycle.all.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('.slideshow').cycle({
fx: 'fade' // choose your transition type, ex: fade, scrollUp, shuffle, etc...
});
});
</script>
</head>
<body>
<!-- 將要播放的物件(img,span,... 啥都可以)放容器裡 -->
<div class="slideshow">
<img src="http://jquery.malsup.com/cycle/images/beach1.jpg" width="200" height="200" />
<img src="http://jquery.malsup.com/cycle/images/beach2.jpg" width="200" height="200" />
<img src="http://jquery.malsup.com/cycle/images/beach3.jpg" width="200" height="200" />
<img src="http://jquery.malsup.com/cycle/images/beach4.jpg" width="200" height="200" />
<img src="http://jquery.malsup.com/cycle/images/beach5.jpg" width="200" height="200" />
</div>
</body>

星期三, 8月 05, 2009

SQL讀出DataTime欄位為0時 會失敗

即datatime的欄位值為0000-00-00 00:00:00時
讀出至datatable會失敗
這時在connection string裡加上這行
allow zero datetime=yes

星期四, 7月 23, 2009

div等其他tag做hover效果

透過<a 可以輕易的做到hover的效果
可是其他tag就不一定會有反應,不同的browser也可能有的會有hover效果,有的沒有
看破還是用onmouseover及onmouseout來做
比較麻煩的是要用this.style.*來做
動一下的感覺
onmouseover="this.style.padding='1px';"
onmouseout="this.style.padding='0px';"

//讓圖變透明
style="opacity:0.4;filter:alpha(opacity=80)"
onmouseover="this.style.opacity=1;this.filters.alpha.opacity=100;"
onmouseout="this.style.opacity=0.8;this.filters.alpha.opacity=80;"

星期二, 6月 23, 2009

特殊符號編碼

今天系統突然沒反應
看了才發現原來xml裡有特殊符號 造成xml判斷錯誤







< 小於&lt;
> 大於&gt;
& 和&amp;
' 單引號&apos;
" 雙引號 &quot;
斷行符號 &#13


特殊字符編碼大全 ... 自已google

透過C#寄發mail

1.直接寄發
透過System.Net.Mail,舊的System.Web.Mail不用了
reference
MailMessage 類別


2.呼叫outlook
需加入參考「 Microsoft Outlook 11.0 Object Library」
Outlook.ApplicationClass app = new Outlook.ApplicationClass();
Outlook.MailItemClass mi = (Outlook.MailItemClass)app.CreateItem(Outlook.OlItemType.olMailItem);
mi.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
mi.To = "yurenju@gmail.com";
mi.Display(new object());


references
C# 呼叫 Outlook

3.呼叫預設email程式
private void StartDefaultClient()
{
string filename = "mailto:jismenon@yahoo.com?subject=Hello&body=Hello&cc=meera@yahoo.com&bcc=jany@yahoo.com&Attach=@C:\\test.txt";
Process myProcess = new Process();
myProcess.StartInfo.FileName = filename;
myProcess.StartInfo.UseShellExecute = true;
myProcess.StartInfo.RedirectStandardOutput = false;
myProcess.Start();
}

references
Opening default Email client from a C# Application


p.s 斷行問題
body裡有斷行時,要改用escape("\n") 或 %0A
否則會沒效果

星期三, 6月 03, 2009

將DataTable裡的Byte column存入access

string[] myPicArrayTitle = new string[] { "Pic1", "Pic2"};
foreach(string title in myPicArrayTitle )
{
string strSQL = string.Format("Update PicInfo Set {0}=@{0} Where PicSN={1}", title, PicSN);
accessAdapter.MdbAccessOLE(strSQL , title,(byte[])dt.Rows[0][title]);
}
public bool MdbAccessOLE(string strSQL,string ColName ,byte[] FileByteArray)
{
this.my_StrConnection = "Provider=Microsoft.JET.OLEDB.4.0;data source=" + this.my_TablePath;
OleDbConnection my_conn = new OleDbConnection(this.my_StrConnection);
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = my_conn;
cmd.CommandText = strSQL;
cmd.Parameters.Add("@"+ColName, System.Data.OleDb.OleDbType.Binary, FileByteArray.Length).Value = FileByteArray;

bool result = true;
try
{
cmd.Connection.Open();
cmd.ExecuteNonQuery();

}
catch (Exception ex)
{
result = false;
SharedAPI.Log_Error("MDB操作失敗, 錯誤訊息:" + ex.Message + " SQL:" + strSQL);
}
finally
{
cmd.Connection.Close();
}
return result;
}

星期一, 5月 04, 2009

開啟預設Browser

利用Process就可了

//直接執行,就是預設的browser
System.Diagnostics.Process.Start("http://www.google.com/");


要指定browser
//指定ie
System.Diagnostics.Process.Start("IExplore.exe", "http://www.google.com");

星期四, 4月 16, 2009

Word合併列印

Word 合併列印
太久沒用 有點忘了
跟Word 97好像不太一樣了
乙級軟應也是過去式啦...
Word 合併列印

同一頁套印兩筆不同的紀錄
初步的合併列印,在每新的一筆都是在新的一頁
如何在同一頁印兩筆不同的記錄咧
這時就插入<>變數即可完成
見以下範例

p.s 在<>變數之後 就會的變數 就會產生下一筆
因為要印第三筆,就貼2個<>變數
Word合併列印教學之二(同一頁套印兩筆不同的紀錄)

C# 列印 Word

列印文件
HOW TO:列印文件
若要列印整份文件
若要列印文件的目前頁面

這寫法還真特別
using Word = Microsoft.Office.Interop.Word;

合併列印

HOWTO:讓 Microsoft Word 由 Visual C# .NET 自動執行合併列印

jqGrid getRowData(id) 發生錯誤

不知為何就是錯了
後來查了一下
是因為利用$(x).load(xx);
把b網頁load進來,而該網頁已經有include jqury.js
把b網頁include jqury.js部份拿掉就ok了

星期二, 4月 14, 2009

Sql Database 加減日期時間

  1. Query裡下日期條件
    SELECT * FROM `Record`
    WHERE YEAR(`RecordDate`) = '2009'
    AND MONTH(`RecordDate`) = '9'
  2. 加減日期時間
    問:取出RecordDate欄位,並加上480分鐘(UTC TimeZone)
    MySQL
    //add 480 mins
    Select DATE_ADD(RecordDate ,INTERVAL 480 MINUTE) as RecordDate From ...
    //substract 30 days
    `UpdateTime` Between DATE_SUB(NOW() ,INTERVAL 30 DAY) And NOW()


    Access
    Select dateadd("n",480,RecordDate) as RecordDate From ...
Value Explanation
yyyy Year
q Quarter
m Month
y Day of the year
d Day
w Weekday
ww Week
h Hour
n Minute
s Second
Access: DateAdd Function

星期日, 4月 12, 2009

改變DataGridView的值或cell顏色

在設定DataSource後,改
dataGridView1.DataSource = DataTable;
foreach (DataGridViewRow dgv in dataGridView1.Rows)
{
row.DefaultCellStyle.BackColor = Color.Red; //改row的顏色
row.Cells["Col_AddUpdate"].Value = "新增"; //改內容值
}


但這樣改是無用的
因為必需在Bind Data的event後
private void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
//在這裡改才有用
foreach (DataGridViewRow dgv in dataGridView1.Rows)
{
row.DefaultCellStyle.BackColor = Color.Red; //改row的顏色
row.Cells["Col_AddUpdate"].Value = "新增"; //改內容值
}
}

星期一, 3月 30, 2009

jQuery 1.2.x 升級 1.3.x 需注意

1.Selector
取input標籤name為go的值
$("input[@name=go]").val(); //原本在 jQuery 1.2.x 上是可行的'
$("input[name=tag]").val(); //但1.3.x後要把@拿掉,不然會出錯

其他原本有加@都要去掉,像[@selected][@checked]等

p.s
[attribute]: 有指定的屬性
[attribute=value] :屬性值為value
[attribute!=value] :屬性值不含value
[attribute^=value] :屬性開頭字串為value
[attribute$=value] :屬性結尾字串為value
[attribute*=value] :屬性值包含value

remark: [attribute=value]與[attribute*=value]看起來很像,但還是有不同
一個是完全符合,一個是有包含,有看到有人寫後者是取多個,應該是不正確的

remark:
不知為何 用[name='test']時,如果全是span是ok的
但如果有個<a name=test>或input 就會只找到這一個

另外
$("XmlParentNode XmlChildNode[name='xx']").xx <==這樣用 好像會找錯
$("XmlParentNode").find("XmlChildNode[name='xx']").xx 才會找對


References:
3 Quick Steps for a Painless Upgrade to jQuery 1.3

星期六, 3月 28, 2009

jQuery取browser值

$(document).height();
$(window).height();

字面上看來window應是視窗的高,document是body的高
但測試後,window的高會比document小
太奇怪了
而且最大化視窗,兩個值還是一樣的...
要再研究


ps.如果是IFrame,值都會比較小

搞清楚clientHeight, offsetHeight and scrollHeight

透過jQuery取高(寬),有三個
1.height()
2.innerHeight() //不含border,padding
3.outerHeight() //包含border,padding及hidden elements

另外javascript本身取document.body有
  • clientHeight
  • offsetHeight
    offsetHeight是自身元素的高度
    *ie7不支援
  • scrollHeight
    scrollHeight是 自身元素的高度+隐藏元素的高度。

其實還是不太懂...

*DIV設Height:100% 沒反應
當在網頁裡多了以下的宣告
就會造成height的100%無效
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4>/strict.dtd">

查了一下
重點是因為body沒有height屬性,所以加入下面這行就可以啦

References
clientHeight、offsetHeight 和 scrollHeight
花点时间搞清top、postop、scrolltop、scrollHeight、offsetHeight

星期五, 3月 27, 2009

常用的正規表達示-統計

  • 統計字串中內某字元或字串出現次數
    /*
    * JavaScript 
    * 找出cloudchen有幾個c
    */
    var str =  "cloudchen"
    var find = "c";
    var reg = new RegExp(find,"g")
    var result = str.match(reg);
    var count = (result)?result.length:0;
    console.log('共:%d次',count);
    reference: JavaScript 統計字串中內某字元或字串出現次數
  • 統計字串中內某字元或字串出現次數
    去-,:,空白,由於"-"是保留字,所以在前面要加\
    //C#.Net
    System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(@"[:|\-| ]");
    string datetime = "2009-01-02 03:04:05";
    datetime = reg.Replace(datetime, "");
    Console.WriteLine(datetime); //輸出20090102030405
    .Net的Regex位於System.Text.RegularExpressions之下

References:
Regular Expression (RegExp) in JavaScript 還可以直接測試
regular language 說明表格

星期四, 3月 26, 2009

如何做行銷計劃

1.動機:告訴別人 為何要做
  • 因為有新產品 (New Product)
  • 因為有新市場 (New Market)
  • 取代舊的Plan

2.分析
分析易有主、客觀認知,如非洲人不穿鞋
分析工具
  • SWOT分析
  • BGC,界定定位

3.製訂行銷策略
4P,6P(People,Procedure)

4.日程表/Budget
甘特圖

星期三, 3月 18, 2009

jQuery的BlockUI

可拖曳 - draggable
自己裝厲害,還自己載了jquery-ui
將blockui的div加上draggable
想想blockui怎麼可能沒有draggable功能
某天看blockui.js 發現了draggable:true;
才知道自己沒看注意demo就有教了
不過blockui的draggable也是依附在jquery-ui,自己載
$.blockUI({
 message: $("#mydiv"),
 draggable: true //加上這行囉
}


設定長寬高
$.blockUI({
 message: $("#mydiv"),
 css: {
 padding: 0,
 margin: 0,
 width: '30%',
 top: '30%',
 left: '25%',
 color: '#000',
 border: 'none',
 cursor: 'auto'
}

當blockUI裡的div或table有限定固定的width時
blockUI套件裡的外框已設定為30%
所以當畫面變大時,就有可能兩旁會有空白

這時就去blockui.js裡把這個拿掉就ok了
就有前幾行而已 很好找的
width: '30%',


錯誤
某些情況下 jQuery會發生錯誤

通常是在這一頁被轉頁後,又下了blockui的操作
錯誤發生在blockui.js裡的
function focus(back){
...
e.focus(); <===這裡...
}

看用catch抓住,再log起來吧...免得跳出錯誤訊息又要被老板唸了
function focus(back){
...
try {
e.focus();
}catch (ex) {
$.unblockUI(); //抓解開block...至少畫面還可以操作
}
}

星期一, 3月 16, 2009

jQuery的accordion 會亂閃亂跳動

利用accordion 完成選單後
click每個選項卻發現選項會跳動
看demo卻好好的
研究了一下 原來demo的html有這一句

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
...
</html>

星期五, 3月 13, 2009

JavaScript開檔 window.open 會跳ie視窗

一般用window.open("xxx.exe")即可
但都會先跳出個ie視窗 再問要不要下載、儲存
可利用ActiveXObject('WScript.Shell')就可以直接執行了
new ActiveXObject('WScript.Shell')).Run('test\\start.exe'); //執行位於test資料夾下的start.exe

完整的範例
< A href="javascript:(new ActiveXObject('WScript.Shell')).Run('test\\start.exe');void(0);"> click me < /a>


利用JavaScript轉址
之前有用過
window.href="http://xxx";
window.location.href="http://xxx";
不過有時都會沒反應
後來用
window.location = "http://xxx";
至少... 還沒問題..

星期四, 3月 12, 2009

如何讓光碟Autorun

autorun.ini
[autorun]
OPEN=xxxx.exe
ICON=yyyy.ico //光碟畫面的icon



如果是跑xxx.hta等,非win32應用程式
功能就像寫在.bat裡
[autorun]
shellexecute=Setup.hta

星期一, 3月 09, 2009

jqgrid 特殊技

設定
1.設定標題欄位高度
不知從那調,硬是拆html找出地方調
var tbTitle = $("#tbRecordList").parent().prev();
$(tbTitle).find("tr:first").find("div").css("height","18"); //12pt字型適用

2.硬將tbody的滑鼠改成"手指"
$("#tbRecordList tbody").css("cursor","pointer");

方法
1.排序

有兩種方法
1.$("#tablename").sortGrid('myname',true); //reload
//If the reload is set to true, the grid reloads with the current page and sortorder settings.
2.$("#tablename").setGridParam({sortname:'myname'}).trigger('reloadGrid');

2.隱藏欄位
使用者選擇
http://www.trirand.com/jqgridwiki/doku.php?id=wiki:show_hide_columns

程式事先隱藏
jQuery("#tbRecordList").hideCol(["recordDate"]);



3.讓某欄位被選到
//setSelection(id,onsetselection) if true the event onSetRow is launched
jQuery("#tbRecordList").setSelection('1',true);


讓header text出現hint
目前還沒看到有什麼method可用
就先手動設定吧
jqgrid會利用建立時,所取的欄位名(name,不是index哦)
加上jqgh_來命名該header的span,如下
jQuery("#jqgh_test").attr("title", "This is title");

星期六, 3月 07, 2009

玩遊戲會重開機

就只有玩遊戲時才會發生
太神奇了
還以為是不是有什麼力量叫我該努力了 不要再玩了
上網查了一下

有人提到是是音效卡的問題
利用DirectX診斷工具
把音效的加速層級從"完全加速"改為"基本加速"
就沒有發生過當機了...

不過自己倒是...又發生了
又研究了一下
發現在同頁面有個「測試DirectSound」
就按了來試試
發現寫說不支援硬體加速
所以改成「沒有加速」
再試試囉

p.s如何啟動「DirectX診斷工具」
1. 按一下 [開始],然後按一下 [執行]。
2. 輸入 dxdiag,然後按一下 [確定]。
3. 在 [系統] 索引標籤上,記下 [DirectX 版本] 列所顯示的 DirectX 版本。
4. 在 [DirectX 檔案] 索引標籤上,檢查每個 DirectX 檔案的版本資訊。
5. 檢查完檔案版本之後,按一下 [結束]。

Reference
玩遊戲重開機~~
如何使用 DirectX 診斷工具

星期四, 3月 05, 2009

批評建議

  • 2011.1.12
    我覺得你們家不是個正常溫暖的家庭 回去面對的不是責罵就是碎念 或是面對一群根本沒有血緣關係的人 到處串門子 我覺得沒有意義

    重要的婚喪喜慶 節日 生日 我該配合回去的我都回去了
    你明明知道我不愛回去 每次我配合回去 你會說謝謝我回去 但之後 卻又會忘記這些 額外要求我要幹嘛幹嘛
    那個家庭是你的責任不是我的 我只需做到我該做的
    或許你會覺得我不孝順 但是你也知道以前我不是那麼不愛回去的人
    其實結婚前後 你爸 你妹 阿公阿嬤 對我都沒有改變 我很感激
    但是你媽變太多了 我很怕
    我真的很怕
    還有一堆婆媽阿姨 我很不喜歡
    但是你媽變太多了 我很怕
    我真的很怕
    還有一堆婆媽阿姨 我很不喜歡
    為什麼別人的媳婦面對的 是一個正常的家庭 就是家人 我卻還要面對 我永遠記不起來的外人
    再來 你回去 跟著你媽東奔西跑 有意義嗎 你要陪的是你爸 你阿公阿嬤
    但你有時候沒有說話的拳利 要跟著你媽辦一堆在我看來沒有意義的大事
    然後回來再跟我說 你沒有陪家人
    這樣對嗎
    最後我要說的是
    我不知道你到比幫我擋了多少
    但我覺得你"號稱長子 長孫" 但說話好像沒有分量
    你在幫我說話的時候 永遠一附站不住腳的感覺
    永遠像個小孩再跟爸媽說謊
    為什麼都沒有辦法理直氣壯
    我媽在我們結婚當天 就告訴你 要當個有肩膀的人
    你要扛起來啊
    為什麼不能說 我回來就好了 幹嘛每次都有帶她 的那種氣魄
    不是藉口
    我需要的不是藉口
    根本不用藉口
    就是"他回來幹嗎?" 我回來就好的那種態度
    我只能說 你每次都擋了7成 最後3成還是掃到我
    如果你講話有份量 還有三成會掃到我嗎
    有責任的時候 就說你是長子長孫大哥
    但說話一點分量都沒有
    像個孩子被擺布
    你都自以為長大了 處理得很好 擋了很多
    但在我看來還是不及格
    所以我很累
    我求你不要自以為長大了 趕快真正長大好嗎
  • 2009.3.5
    • R:Error Handling要加強
    • M:仔細檢查,再把結果給別人
    • A:遇到問題多討論,避免做白工
    • D:
      • PDCA要做好,規劃有做好,就不會有問題
      • 管理:溝通文件要做好
      • 態度要改進,不再是學生,錯了有人handle;商業軟體,要以滿足客戶為出發點,不是功能達到即可
  • 2008年工作回顧
    • 工作上的態度,有時表現失常,造成其他人心裡不舒服
    • 需加強底層的觀念,溝通技巧、態度可以再柔軟一些
    • 工作結果需多檢查再丟出來

    工作都1年了,還是這樣
    下個星期要壓光碟了,程式還會當

軟體專案管理

《人月神話》
《最後期限》
《與熊共舞》
《你想通了嗎?》

《溫伯格的軟體管理學》
如果《人月神話》是一種反思與沉澱,那麼《溫伯格的軟體管理學》就是軟體專案管理的最佳實務!

星期三, 3月 04, 2009

ClickOnce 和 Windows Installer 的比較

用了一陣子的ClickOnce
雖然已知ClickOnce有先天的限制
不過覺得相當簡單好用
所以下定決定要克服這些限制
卻也花了不少時間查別人如何做
雖然克服了一些 但距正規安裝落差還是一大段
最後還是放棄了
乖乖的去學InstallShield

鏈結有比較表
先天無法克服的...就不要硬拚了...
有做出來就還可偷笑一下...
做不出來不僅累了自己 還要被人定
ClickOnce 和 Windows Installer 的比較表

星期二, 3月 03, 2009

自定螢幕解析度

最近看LCD大降價 想台大螢幕的來取代17吋的LCD
聽信網路謠言說LCD螢幕16:10比較適合看網頁
於是乎 買了Philips 220CW 22吋大LCD

開始一看 最佳解析度 1680*1050 60Mhz
卻發現顯卡沒有此選項只有1600*1024 ...
那就1600*1024先開來看看吧
oh no~~~ 除了被壓成扁身外 居然連字都變糊的

把解析度調低至1280*800 才變清析
原想那就這樣吧 一向來逆來順受
可是實在不甘心 雖然LCD已經跟前陣子比較來便宜了許多
但是花了錢 卻只能用較低的解析度
明明畫面這麼大 桌面的圖示、字型都可以再小一點 不甘呀~~~
好吧 試著亂調不行、重灌LCD,顯示卡Driver都失敗

原廠軟體出動
實在是「有步想到無步」
拿出LCD廠都會附的沒用光碟
灌了原廠附的軟體

看到了一個Resolution 字眼應該滿像的
又看到說明有寫clear text... 就是這個啦
就給他按下去
果然....字變清析了...
ya 又讓我回抱這22吋的感動

再拚1680*1050
事隔1年多
雖然字已是清析 但依然不是 1680*1050
畫面還是被壓成1600*1024 圖都扁扁的 看了就覺得很"礙優"
想一想 沒有這個1680*1050 那是不是有軟體可以自定這個解析度
後來看到NVIDIA的軟體可以自定 不過我的顯卡是Ati的 慘念
最後找到PowerStrip這個軟體
我的22吋總算出現了最佳解析度.... 而且連字也是清析的..
嗚 好感動

Reference:
【教學】為繪圖卡及螢幕設定自訂解析度

星期四, 2月 26, 2009

InstallShield 將'必要條件' 來源設為與source相同位置

版本:InstallShield 2009,2010 - Premier or Professional
設為跟source相同位置後,就是要下載相關的檔案

1. 設定必要條
在Project Assistant裡勾選完「必要條件」(Prerequirist)

2. 啟動Release Wizard
Premier及Professional都可以到「Installation Designer」界面
再點選底下的 「Meda/Releases」
右側會出現「Releases」的樹狀圖,再其右鍵「Release Wizard」

 









 3.設定"必要條件"資料來源
勾選Extract from Setup.exe

這時便會要求要下載"必要條件"












4.勾選要下載的"必要條件"
一步步往下做,就會發現Wizard會詢問了
過程中選擇.net framework時,勾選符合語系的檔, 另外原文版的也要勾選

p.s. 原文的.net framework為「.Net Framework Version X.X Redistributable Package」
找 了好久...



 選好後,下一步 便會自動下載啦












p.s 直接在Releases右鍵Release Wizard是會產生一個新的Build Installation程序
如果要 利用Project Assistant的Build Installation產生安裝檔
要在該樹狀結構選擇 「PROJECT_ASSISTANT」底下的檔右鍵Project Assistant

如果沒看到「PROJECT_ASSISTANT」,就先利用Project Assistant產生一次安裝檔後,就會出現了


p.s. Express版本沒試過

星期二, 2月 17, 2009

當系統程式掛時 給於使用者提示

就在系統掛時 還可以給個提示...
說是windows有問題....不是我寫的程式掛了 哈

1.先catch exception
系統會掛 通常發生在exception發生了,但沒有catch到
所以可以用ThreadException來抓到沒有handle到的excpetion
Application.ThreadException += new ThreadExceptionEventHandler(HandleException);

而Application.ThreadException只能handle到主執行緒上的Exception
當有thread或某些情況下,這event就不會被觸發
所以得另外用AppDomain.CurrentDomain.UnhandledException
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(UnhandledException);

細節查關鍵字就可以找到了

2.Report Error


*註
UnhandledExceptionEvent在執行編譯過release下的exe才會抓到
UnhandledExceptionEventdebug的抓不到,而ThreadExceptionEvent好像debug模式下可以

Reference
C# Tutorial - Dealing With Unhandled Exceptions
如何在程序中友好提示錯誤

演講

事前準備
1.聽眾背景
決定topic及內容深淺
2.可用媒介
先探聽場合可用的媒介,以免準備了投影片,現在卻沒投影機可用
3.內容
不要讓聽眾讀,特別是投影片,遵守6*6原則
英文每行不超過6個字,每頁不超過6行
中文每行不超過6個詞, ...
投影片速度 1頁/1分 ,太多聽眾不會有印像

演講時
1.站姿:自然即可
2.視線接觸:與聽眾有眼神接觸,抓住他的注意
3.距離:看到想睡的人,可以走近他,讓他不敢睡
4.速度:
10~20人,120~150字/分
30人以上,90~120字/分
5.加深印像
可重覆的帶重要的topic,讓聽眾重覆複習加深印像

星期日, 2月 15, 2009

js顯示loading gif 動畫不會動

利用一個click事件
要顯示loading動畫的gif
可是圖片卻會卡住不會動
就像沒開thread一樣的卡住畫面

想了半天還是不知為了
後來看了程式碼
&lt a href="javascript:void(0);"&gt &lt img src="xx"&gt
當初利用anchor tag來當做click事件的元件
其中javascript:void(0) 是當初為了取代# 而用
就在亂試之下,改回#字後 重新click居然可以了
真是感動...
先寫下了 免得以後又發生

星期六, 2月 14, 2009

.Net Process相關應用

.net的Process
除了可以自己new起來外
還加參數
myProc.StartInfo.Arguments = "xx";

偵測Process結束事件
myProc.Exited += new EventHandler(myProcExit);

星期五, 2月 13, 2009

讓程式在Vista下 以「系統管理者」身份執行

在Vista下
當程式需要有系統管理者權限時
Vista是通過manifest來判斷所需的權限
也就是 YourProgram.exe 就會看同位置下的 YourProgram.exe.manifest (xml檔)
主要有2個步驟
1.先編這個xml檔
(1)複製「專案/Properties」下的app.manifest
(2)再把裡的name修改成YourProgram.exe
(3)把的level改成requuirAdministrator
*如果沒app.manifest這個檔案,右鍵「專案/屬性」下的分頁「安全性」,把啟用ClickOnce安全性設定取消就會出現了


2.編完後,利用mt.exe 來下
mt -manifest YourProgram.exe.manifest -outputresource:YourProgram.exe

*編完得到失敗結果:
Code:9009 => 找不到mt.exe , 找出mt.exe 再加入
通常會在C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin 底下找到mt.exe
到環境變數裡Path設定吧
C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin;
Code:31 => 還不是很確定,就多按幾下 或切個畫面就可以了

Reference中有詳細的圖文說明
就照著步驟做吧
「就感心」的是 筆者有教在「建置後事件命令列」中,放進步驟2
也就是當你的程式compile後,就會自動來執行這段指令。
不然多個步驟 忘了編就麻煩了
*將manifest檔放到bin/Release下

Reference

如何讓你的C#程式在Vista上以「系統管理者身分」執行

星期四, 2月 12, 2009

利用WM_DEVICECHANGE抓Port Name

除了用監聽Usb event外
還可利用WM_DEVICECHANGE來攔截相關訊息
由於網路上多是C/C++的實作
真不容易找到C#的 但又沒有完整的用C#查Port Name
在Reference[2]有相關的教學,但沒有查Port Name
就看了MSDN的說明,依樣畫葫蘆做出來了
Reference[2]裡有做了 Win32的class
[StructLayout(LayoutKind.Sequential)] public class DEV_BROADCAST_PORT {
public int dbcp_size;
public int dbcp_devicetype;
public int dbcp_reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public char[] dbcp_name;
}

然後在DBT_DEVICEARRIVAL裡,再改成用剛寫的StructLayout DEV_BROADCAST_PORT
if (m.WParam.ToInt32() == DBT_DEVICEARRIVAL)
{
Marshal.PtrToStructure(m.LParam, typeof(Win32.DEV_BROADCAST_HDR));
int dbccSize = Marshal.ReadInt32(m.LParam, 0);
int devType = Marshal.ReadInt32(m.LParam, 4);

if (devType == Win32.DBT_DEVTYP_PORT)
{
Win32.DEV_BROADCAST_PORT dip = (Win32.DEV_BROADCAST_PORT)
Marshal.PtrToStructure(m.LParam, typeof(Win32.DEV_BROADCAST_PORT));
string csTemp = "COM" + dip.dbcp_name[6].ToString(); //dbcp_name是一串字,在第6個是COM的Number
//MessageBox.Show(csTemp + " arrived/removed");
listBox1.Items.Add(csTemp + " arrived/removed");
}
}


Reference
1.MSDN WM_DEVICECHANGE Message MSDN的說明
2.Retrieving dbcc_name string from a DEV_BROADCAST_DEVICEINTERFACE structure 有VB及C#的實作

星期二, 2月 10, 2009

開啟網芳超慢

不知為何每次要開啟網芳就很慢
但利用ip位置 直接開啟 倒是挺快
上網survey了一下
利用下面的方法 果然有變快

把 W2K、WinXP 登錄檔中
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\RemoteComputer\NameSpace
下面的 {D6277990-4C6A-11CF-8D87-00AA0060F5BF} 刪除,
不需要重開機馬上就見效,Win2k 及 WinXP 均有效。

Reference
winxp 網路芳鄰開啟超慢
Windows XP 系統調校秘技

星期五, 2月 06, 2009

USB轉Comport時 查DeviceID及佔用的Comport name

利用WQL查詢
位置:「root\\WMI」下的「MSSerial_PortName」
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\WMI",
"SELECT * FROM MSSerial_PortName");


MSSerial_PortName下有三個屬性
1.Active
2.InstanceName //即DeviceID
3.PortName //佔用的Port name

找USB插入的佔用的Port name
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\WMI",
"SELECT * FROM MSSerial_PortName Where InstanceName like '%VID_067B&PID_2303%'"); //這裡是利用Prolific做的驅動程式

foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("MSSerial_PortName instance");
Console.WriteLine("Find Beacon at Port:{0}", queryObj["PortName"]);
Console.WriteLine("-----------------------------------");
}

p.s 在vista下 會因為UAC (User Account Control) 而會遇到Access Denied
解決方法
1.以 run as administrator 的方式執行就能動
2.到「控制台/使用者帳戶」 把UAC(使用者帳戶控制)關閉,就可以了
3.想要程式自動設好... 讓程式在Vista下 以「系統管理者」身份執行

Reference
1.A Useful WMI Tool & How To Find USB to Serial Adaptors
2.Vista 底下如何加入WMI provider dll?

星期三, 2月 04, 2009

C#查詢Windows已安裝的軟體

找某軟體是否已安裝

  1. 先取得軟體安裝路徑
    可利用regedit.exe,到LocalMachine下的Software查軟體安裝註冊表
    比如說要查Prolific Technology INC 公司的 PL-2303 USB-to-Serial
    得知路徑為
    string path = "Prolific Technology INC\PL-2303 USB-to-Serial";
  2. 程式寫法
    程式的話,就可以透過Microsoft.Win32.Registry 達成
    比如說要查Prolific Technology INC 公司的 PL-2303 USB-to-Serial
    在程式註冊表中會在SOFTWARE資料夾中Prolific Technology下找到PL-2303 USB-to-Serial
    如果可以找到代表有安裝,所以程式可寫成
    regkey = Registry.LocalMachine.OpenSubKey("SOFTWARE", true).OpenSubKey(@"SOFTWARE下的路徑", true); 

以下為完整範例
//先引用Microsoft.Win32
using Microsoft.Win32;

public bool findSoftwareInstalled()
{
  try
  {                   
    //找PL-2303 USB-to-Serial 是否安裝
    string path = "Prolific Technology INC\PL-2303 USB-to-Serial";
    RegistryKey regkey = Registry.LocalMachine.OpenSubKey("SOFTWARE", true).OpenSubKey(@path , true);
    if (regkey == null)
    {
       //"註冊表內無儲存安裝訊息";
       return false;
    }
    else
    {
      //已安裝,可利用regkey.GetValue("xxx").ToString(); 取得相關資訊
      return true;
    }
  }
  catch (Exception ex)
  {                
    Console.WriteLine(ex.Message.ToString());
    return false;
   }
}

*Clickonce安裝位置
利用clickonce安裝的軟體不會在LocalMachine下的Software
而會是在CurrentUser的Microsoft\Windows\CurrentVersion\Uninstall下

利用WQL 找Windows裡相關資訊

先引用WQL所在的namespace
using System.Management; //要先在專案的參考加入System.Management


找Driver
public bool getDrivers()
{
ManagementScope scope = new ManagementScope(@"root\CIMV2");
ObjectQuery query = new ObjectQuery("WQL", "SELECT * FROM Win32_SystemDriver");
ManagementObjectSearcher search = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection col = search.Get();

if (col.Count == 0)
{
return false;
}

Console.WriteLine("Win32_SystemDriver instance (Total Found:{0})", col.Count.ToString());
Console.WriteLine("-----------------------------------");
foreach (ManagementObject obj in col)
{
string driverlist = obj.ToString().ToUpper();
if (driverlist.Contains("SER2PL")) //此例是找SER2PL,更換你要的Driver Name
{
Console.WriteLine("找到Driver已安裝,Name: {0}", obj.ToString()); //name 是 Unique identifier for the service
return true;
}
/*
//印出所有屬性
foreach (PropertyData propertyData in obj.Properties)
{
ManagementBaseObject mbo = null;
if ((mbo = propertyData.Value as ManagementBaseObject) != null)
{
foreach (PropertyData prop in mbo.Properties)
Console.WriteLine("{0} - {1}", prop.Name, prop.Value);
}
}
* */
}
search.Dispose();
col.Dispose();

return false;
}


References:
可直接下拉查詢相關的資訊
WMI Code Creator v1.0

星期三, 1月 21, 2009

ClickOnce 必要條件 - 從相同位置下載必要條件

搞死人了
怎麼樣都無法設定好
在老板的淫威逼迫下 總算把這搞定了

狀況
為了讓使用者不必透過網路下載「必要條件」
所以在ClickOnce「必要條件」設定「從應用程式的相同位置下載必要條件」
但都會發生類似以下令人抓狂的錯誤:
1.錯誤 無法發行,因為無法建置專案錯誤。
2.錯誤 必要條件的安裝位置沒有設定為「元件廠商的網站」,且磁碟上找不到項目 '.NET Framework 2.0' 中的檔案 'DotNetFX\instmsia.exe'。如需詳細資訊,請參閱 [說明]。
3. 錯誤 必要條件的安裝位置沒有設定為「元件廠商的網站」,且磁碟上找不到項目 '.NET Framework 2.0' 中的檔案 'DotNetFX\WindowsInstaller-KB893803-v2-x86.exe'。如需詳細資訊,請參閱 [說明]。
4.錯誤 必要條件的安裝位置沒有設定為「元件廠商的網站」,且磁碟上找不到項目 '.NET Framework 2.0' 中的檔案 'DotNetFX\dotnetfx.exe'。如需詳細資訊,請參閱 [說明]。
5.錯誤 必要條件的安裝位置沒有設定為「元件廠商的網站」,且磁碟上找不到項目 '.NET Framework 2.0' 中的檔案 'DotNetFX\langpack.exe'。如需詳細資訊,請參閱 [說明]。


問題點:需下載相關的檔案,並放到對的位置,問題就在這位置不知要放哪,且依SDK不同放的位置也不同,而且3.5還需設定xml檔


針對不同版本的Framework會有不同的解決方法
A.必要條件.Net Framework 2.0版
Step1 環境確認
IDE:C# 2008 Express

Step2 下載必要檔案
需要4個檔案,click鏈結可以直接下載檔案,如果鍵結斷了,可以直接search關鍵字
1.instmsia.exe
2.WindowsInstaller-KB893803-v2-x86.exe
3.dotnetfx.exe
4.langpack.exe

Step 3 放至指定資料夾
將全部的檔案丟到
C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages\DotNetFX
在錯誤訊息中指出,這個資料夾缺了這四個,但即使將這四個檔放進這資料夾,還是會出現潮少langpack.exe,也就是說錯誤訊息剩下2個
1.錯誤 無法發行,因為無法建置專案錯誤。
2.錯誤 必要條件的安裝位置沒有設定為「元件廠商的網站」,且磁碟上找不到項目 '.NET Framework 2.0' 中的檔案 'DotNetFX\langpack.exe'。如需詳細資訊,請參閱 [說明]。

明明都寫這位置了,卻還是不行,看了一下該資料夾下還有個「zh-CHT」
就順手把 langpack.exe 丟進去,結果就成功了
大家試試吧

References:
VB2005 Express 部署問題
VS bootstrapper packages for .NET Framework 2.0 SP2 and 3.0 SP2 available for download

B.必要條件.Net Framework 3.5 SP2
照著網誌的做法就可以成功了
ClickOnce 發佈時,一起發佈 Framework 套件
ClickOnce 暨 Framework 3.5 發佈失敗的問題

星期日, 1月 18, 2009

如何維持.net程式單一執行個體應用程式

VB專案可以很開心的依以下路徑設定 就完成這限制
「專案=>屬性=>應用程式=>建立單一執行個體應用程式 」

不過其他的如C#等語言 就得自己寫程式
C#裡
/*
Code Snippet
Just add that piece of code (here in C#) in your main method (you need to
include the System.Diagnostic namespace) :
*/
Process currentProcess = Process.GetCurrentProcess();

Process [] allProcesses =
Process.GetProcessesByName(currentProcess.ProcessN ame);

if (allProcesses.Length > 1)
{
MessageBox.Show(currentProcess.ProcessName + " is already running !",
currentProcess.ProcessName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
//do your stuff here
}

VB
/*
Code Snippet
In the VB.NET application:
*/
Dim m As Mutex = _
New Mutex(False, "{11C92606-65D9-4df2-9AEA-B6A4DA91BCE2}")
If m.WaitOne(10, False) Then
Application.Run(New Form1())
m.ReleaseMutex()
Else
MessageBox.Show("Application already running!")
End If


Reference:
[VB 2005]如何避免程式(.exe)連開兩個以上

後記
除了維持單一執行應用程式外
應該不只是關閉新開的程式,而且要喚起即有的程式視窗
據說一般是利用hook達成... 等研究出來再補上

ClickOnce加入桌面Shortcut

ClickOnce本身沒支援
不過還是有人硬寫出來了

/// <summary>
/// This will create a Application Reference file on the users desktop
/// if they do not already have one when the program is loaded.
// If not debugging in visual studio check for Application Reference
// #if (!debug)
// CheckForShortcut();
// #endif
/// </summary>
void CheckForShortcut()
{
ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment;
if (ad.IsFirstRun)
{
Assembly code = Assembly.GetExecutingAssembly();
string company = string.Empty;
string description = string.Empty;
if (Attribute.IsDefined(code, typeof(AssemblyCompanyAttribute)))
{
AssemblyCompanyAttribute ascompany = (AssemblyCompanyAttribute)Attribute.GetCustomAttribute(code,typeof(AssemblyCompanyAttribute));
company = ascompany.Company;

}
if (Attribute.IsDefined(code, typeof(AssemblyDescriptionAttribute)))
{
AssemblyDescriptionAttribute asdescription = (AssemblyDescriptionAttribute)Attribute.GetCustomAttribute(code, typeof(AssemblyDescriptionAttribute));
description = asdescription.Description;
}
if (company != string.Empty && description != string.Empty)
{
string desktopPath = string.Empty;
desktopPath = string.Concat(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "\\", description, ".appref-ms");
string shortcutName = string.Empty;
shortcutName = string.Concat(Environment.GetFolderPath(Environment.SpecialFolder.Programs), "\\", company, "\\", description, ".appref-ms");
System.IO.File.Copy(shortcutName, desktopPath, true);
}
}
}


remark
1.clickonce利用company name在「開始/程式集」中建立路徑,而description為「捷徑檔的名稱」
所以記得在clicknoce中設置company及description,否則上面的程式會找不到
2.另外clickonce的「發行/選項」的「產品名稱」及「應用程式/組件資訊」的「描述」,兩者要一致,不然會找不到
說明:
「發行/選項」的「產品名稱」是clickonce部署後,在程式集命名捷徑的命稱
「應用程式/組件資訊」的「描述」是上述程式asdescription.Description所取得的,所以這一項要跟產品名稱相同,才找的到clickonce設的捷徑

References:
How to add Desktop Shortcut to ClickOnce Deployment Application

星期四, 1月 15, 2009

強迫退出程序

不知何時手賤加了什麼東西
利用Application.Exit()要將程式碼退出
就會發生「無法使用已經從其基礎 RCW 分離的 COM 物件」
不知是不是加了NotifyIcon的關係
總之... 給他強迫退出 Environment.Exit(0);
就開心的解決了

p.s 強迫退出後,NotifyIcon的圖示還會留著,所以要exit前,先將NotifyIcon.dispose();

Reference:
强制退出WinForm程序之Application.Exit和Environment.Eixt

星期三, 1月 14, 2009

JavaScript Regular Expression - 驗證

如何使用Regular Expression
//驗證email格式
var pattern = new RegExp();  
pattern = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
if (!pattern .test(email)) {
return false; //"email格式不對"
}
其實也不用特別再new RegExp,直接給pattern就可以了
javascript是這樣啦,其他的語言應該不行

  • 驗證email格式 *一定要有@
    pattern = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
  • 驗證密碼
    *至少有一個數字
    *至少有一個小寫英文字母
    *至少有一個大寫英文字母
    *字串長度在 6 ~ 16 個字母之間
    var pattern = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,16}$/;
    
    //簡單點,不考慮英文大小寫
    var pattern = /^(?=.*[a-zA-Z]+)(?=.*\d+).{6,16}$/;
Reference:
使用 Regular Expression 驗證密碼  

星期一, 1月 12, 2009

browser間的支援度

iframe問題
iframe doesn't work in IE7
原本利用屬性width及height設為100%,在ie7就會掛了
查了一下,利用style來設定就搞定
< IFRAME SRC='gnagna.htm' STYLE='width:100%;'>< /IFRAME>

星期四, 1月 08, 2009

利用PrintDocument列印

.net提供PrintDocument 的列印功能
以下是主要提供的功能
  • PrintDialog 顯示標準列印對話方塊,供使用者選擇印表機與變更印表機選項
  • PrintPreviewDialog 在預覽視窗中顯示報告內容
  • PrintPreviewControl 將第一頁報告內容顯示於可納入表單中的控制項
  • PageSetupDialog 顯示標準頁面設定對話方塊,讓使用者可選擇直向或橫向列印,以及變更邊界設定


new PrintDocument的物件
要自己handle PrintPageEvent
再用Print()來觸發PrintPageEvent
remark: 當利用PrintPreviewDialog時,ShowDialog即等同於Print()
也就是說會觸發PrintPageEvent

詳細內容可見reference

Reference:
列印的極限能力 有詳細的說明