星期日, 12月 28, 2008

好用的雨刷

相較於這支超不耐用的雨刷這支雨刷我整整用了一年三個月。所以安托華的雨刷所然要價250元,相對起來比起在B&Q的花了199元買的雨刷只用了一個多月,顯然安托華的划算一點。

不知是安托華的運氣比較好,還是汽車專賣店的品質其實比大賣場的品質能夠好一點。個人覺得
大賣場因為要上架費、管銷費用等,品質先不論有沒有顧到,至少賣家的利潤一定非常低。至於汽車精品店的通路我就不怎麼清楚了。不知是否會在Cost down下犧牲品質。


DSC_6909


接下來的接力的長期雨刷追蹤是Tido軟骨雨刷,這是Made in Taiwan的喔。希望能打敗大陸製造的雨刷。

星期日, 11月 16, 2008

今年夏天最大的成就

我不曾請過游泳教練,所有的泳式就靠著親朋好友的教導完成自由式、蛙式以及立泳,好歹練成丟到水池撐個幾十分鐘淹不死的程度。至於姿勢好不好看、速度快不快、游起來效率高不高就不在要求範圍內了。

今年夏天,尤於老婆在社區的泳池內請救生員,我就趁這個機會去晨泳,晨泳時經常只有我一個人獨享整個泳池。於是我就請救生員泳姿的問題。救生員(其實是老闆)相當在行,一下就指出我姿勢的錯誤地方,使得我原先游的相當慢的自由式大有進步。原先我的自由式只要游個五十公尺就覺得很喘了,經過指導後,游個二百公尺大概不成問題,不過因為還沒有養成習慣的關係,很多時候會到了要換氣的時機而忘了換氣而導致換氣不順。這個問題我覺得不大,畢竟是習慣的養成,只要多加練習就可以了,總比之前是連方法都不曉得的好太多。

二弟將今年夏天的後期的我的自由式拍了下來,說實在的,我自己都覺得進步非常多,很得意呢。

Treo 650

Palm這間不長進的公司多年前推出Treo 180 PDA phone (單色160*160 resolution), Treo 270 (彩色160*160 resolution),演化到Treo 600 (彩色160*160 resolution, 不可更換電池)。我一直都不曾心動過,一直到推出這支劃時代的手機,可說是改進了所有的缺點。 彩色320 *320 解析度,可更換的電池,再加上超有涷頭的電池,我充一次電大約可以使用四天。所以雖然拿起來像磚頭,可是反應速度快,功能強大。剛上市時價位約在台幣二萬二左右,我在2005年三月份參加Palmislife的團購以入手價18000購得。

三年半過去後,新的手機如雨後春筍般的冒出,Palm這間不長進的公司只再推出了因為Treo 650是含鉛製程的無法在歐盟販售的Treo 680以及2008年推出的低價小巧版本Centro。我看著外殼越來越舊的Treo 650,心中完全沒有想要換機的念頭,只覺得這支手機怎麼這麼耐用又好用。這在拍賣網站上可以證明,只要是堪用的Treo 650手機,拍賣價沒有低於五千元的。這在電子產業裡真是不可思議的高價。

沒想到因為原廠皮套的損壞,讓我的外殼急速損毀,等到我查覺到是因為皮套破損的關係導致外殼的過度磨擦後,外殼已經破裂了,還好以前的同事讚助我一組外殼。結果我在換完外殼後,一時腦殘手賤又拿起WD-40往LCD screen噴,這一噴整個LCD screen就被我噴成暗暗的。外殼雖然換新,但LCD確變成無亮度,隨後再網上四處尋找有無可換的LCD,甚至曾經想要送原廠維修花上USD170美金更換良品確因為這支當初是美規電信業者機而不納入Palm的維修體系內而作罷。最終於大陸託小弟買得取代零件。但是這大陸賣的零件不是很好,會有觸控偏移的問題(果然是黑心商品的集散地啊),再加上因為嘗試拆裝LCD module可能過於多次,我的Treo 650終於宣告掛點,電話雖然能接能打,但螢幕已經變成完全無輸出了。所有的努力在這裡終於劃下句點,我的Treo 650搶救大作戰計畫終告失敗。

後續:面對這支服役我整整三年半的手機,心中說真的還是有感情在的。為了能讓它能繼續發揚光大,我在PalmIsLife網站上以殺肉機的名養義賣出800元價位,捐款就直接充做網站的經費了。

Treo 650 LCD module
剛換完新殼但是LCD暗淡的Treo 650

再補上之前外殼已經不行的老Treo 650

KICX0899

星期二, 8月 19, 2008

Identify USB/IDE/SD Mass Storage Device (Disk Drivers)

Mass Storage Device會被認成是一個Disk,如果要知道這顆Disk是屬於USB或是SATA/IDE Interface,透過標準C Library或是File Management或是Disk Management都無法得知,這些資訊被隱藏起來了。

我寫了一個C++ Class利用Windows Setup API取得系統內有幾個USB Type的Disk。如要判斷是否為Secure Digital或是IDE可自行另行判斷。

massstorage.h

#pragma once

/**
This is the Mass Storage Device Class Library.

Support Help Function to Mass Storage Class.
*/
class CMassStorage
{
public:
CMassStorage(void);
~CMassStorage(void);
/**
Identify a volumn name is exist or not.
\param volname input volumn name
\return true if exist, 0 do not exist.
*/
int isVolumnNameExist(const CString & volname);
/**
Overloaded help function, to supply more argument
\param volman to be identify
\param drv driver letter if the identified voluman exist.
\return true if exist, 0 do not exist.
*/
int isVolumnNameExist(const CString & volname, CString & drv);
int getUSBMsc(void);
};




massstroage.cpp

#include "StdAfx.h"
#include "MassStorage.h"

#include
#include
#include

CMassStorage::CMassStorage(void)
{
}

CMassStorage::~CMassStorage(void)
{
}


int CMassStorage::isVolumnNameExist(const CString & volname)
{
CString dummyDrv;
return isVolumnNameExist(volname, dummyDrv);
}

int CMassStorage::isVolumnNameExist(const CString & volname, CString & drv)
{
TCHAR disk[MAX_PATH]= _T("C:\\");
TCHAR drvltr; // driver letter
TCHAR buf[MAX_PATH];

// scan the disk from C to Z
for (drvltr = 'C'; drvltr <= 'Z'; drvltr++) {
disk[0] = drvltr;
DWORD dummy;
if (GetVolumeInformation(disk, buf, MAX_PATH, &dummy, &dummy, &dummy, NULL, 0)) {
// the driver exist, check the logical volname.
if (volname.CompareNoCase(buf) == 0) {
drv = disk;
return TRUE;
}
}
}
return FALSE;
}

/**
Return the USB mass storage device number
If there are any errors, the returned USB number is still 0.
This function check the device identify if prefixed by "USBSTOR"
\return number of USB mass storage device.
*/

/**
For other GuidClass, search Microsoft for "System-Supplied Device Setup Classes"
*/
DEFINE_GUID(driverGuidConst, 0x4d36e967, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18);


int CMassStorage::getUSBMsc(void)
{
HDEVINFO hdevinfo;
GUID driverGuid = driverGuidConst;
int nousb = 0;
const static WCHAR USB_MASS[]=_T("USBSTORE");

// Get the device setup class handler, for disk driver.
if (INVALID_HANDLE_VALUE != (hdevinfo = SetupDiGetClassDevs(&driverGuid, NULL, NULL, DIGCF_PRESENT ))) {
// Retrieve every instance of this class.
int index = 0;
SP_DEVINFO_DATA data;
data.cbSize = sizeof(SP_DEVINFO_DATA);

while (SetupDiEnumDeviceInfo(hdevinfo, index, &data)) {
ULONG buflen;
// Get the size of device ID buffer.
if (CR_SUCCESS == CM_Get_Device_ID_Size(&buflen, data.DevInst, 0)) {
// if the device is exist, then buflen > 0.
if (buflen > 0) {
WCHAR * buf = new WCHAR[buflen];
CM_Get_Device_ID(data.DevInst, buf, buflen, 0);
if (0 == wcsncmp(USB_MASS, buf, sizeof(USB_MASS)/sizeof(WCHAR))) {
nousb++;
}
delete buf;
}
}
index++;
}
// must free the handle to device information.
SetupDiDestroyDeviceInfoList(hdevinfo);
}

return nousb;
}


星期三, 8月 13, 2008

如何在Blogger裡內嵌程式碼

忘了那裡看到的,原始程式的出處在http://code.google.com/p/google-code-prettify/

使用方法很簡單,可以參考http://google-code-prettify.googlecode.com/svn/trunk/README.html

簡略介紹如下:< >
  1. Download source code, 放在一個固定伺服器,目前我有一個Hinet Myweb 伺服空間,在可預見的未來我大概都不會取消,所以你可以直接使用,位置在http://double.myweb.hinet.net/web/prettify.css and http://double.myweb.hinet.net/web/prettify.js
  2. 在你的Google Template裡,加上


  3. <link href="http://double.myweb.hinet.net/web/prettify.css"
    type="text/css" rel="stylesheet" />
    <script type="text/javascript"
    src="http://double.myweb.hinet.net/web/prettify.js">
    </script>


    在你template裡,尋找<body>,改成

    <body onload="prettyPrint()"> ......</body>


  4. 當要post code時,直接使用以下格式,其中的lang-html可以為lang-cpp, lang-html....等格式。


  5. <pre class="prettyprint lang-html">...</pre>



目前支援的語言格式有"c", "cc", "cpp", "cs", "cyc", "java", "bsh", "csh", "sh", "cv", "py", "perl", "pl", "pm", "rb", "js", "html", "html", "xhtml", "xml", "xsl"。 對我來說已經相當夠用了。