My Dad's Photos

Friday, June 05, 2009

Google Gadget for Linux - 在 Ubuntu/Linux 上使用 Google 桌面小工具

現有的 Google 桌面 for Linux 版本,僅支援個人電腦的資料搜尋功能,沒有在 Windows 版本底下可以使用的小工具功能,如果要使用小工具的功能,那就要透過 "Google Gadget for Linux" 這個開源碼專案。Google Gadget for Linux 有各種 Linux 版本可用的套件,可參考該專案的Wiki 網頁

而在最近版的 Ubuntu 9.10 jaunty 也直接包含這個套件,安裝上就很容易了︰

GTK版本︰
sudo apt-get install google-gadgets-gtk
QT版本︰
sudo apt-get install google-gadgets-qt

如果想嘗試最新版本,也可以參照其說明編譯最新原始碼 :)
開始想去寫一些小工具來玩了,哈~

借用一下專案網站上的截圖 :p

Friday, May 08, 2009

玉山銀行的網路ATM - 原來我也可以用網路ATM!

網路ATM應該已經出來很久了,不過我一直沒有嘗試過,不清楚是如何操作的,
一個很大的原因是,我手邊並沒有讀卡機,又不想沒事花錢去買一台。

最近因為報稅的關係,想去申請了自然人憑證,但是需要讀卡機,
正當我在網路上看相關資料時,無意中瞄到筆電側面的SC兩個字,
據我以前看說明書,這是Smart Card插座...

Smart Card == 晶片卡 ??

當時在腦中浮現這個疑問,於是趕快上網一查... 真的耶!!
在買了2年多以後,我終於知道我這台筆電可以讀晶片卡,可以用網路ATM!!!(好遲鈍 Orz)

話說雖然有讀卡機,但是現在市面上的銀行網路ATM,都是以IE的ActiveX寫成,
就一個Firefox使用者來說,十分的不便,不過沒關係,玉山銀行很貼心的為Firefox使用者開發了plugin,所以至少在Windows底下的Firefox是可以使用的。
(ps. 現在王山銀行也推出可用於 Linux 版的套件囉! )

其實第一次用網路ATM是在中華電信的MOD上面,非約定帳戶轉帳實在是很方便啊
尤其是在信用卡繳款截止日時,可以想到趕快繳,不怕麻煩或忘記。
想到被中信扣了2次遲繳罰款就覺得很冤...(氣到我剪卡了XD)

這邊是要替玉山銀行廣告一下,因為它有提供 Firefox 支援,
雖然我現在沒有玉山帳戶,但是用它的網路ATM倒是很方便喔~~

Tuesday, April 14, 2009

DICOMViewer - 顯示醫學DICOM影像的Viewer

最近花了點時間,以DCMTK函式庫為基礎寫了一個DICOMViewer,
這個程式只能瀏覽本地端位於硬碟內的DICOM影像檔,
不具有DICOM影像傳輸以及開啟DICOMDIR的功能。

此程式包含了一個檔案瀏覽器以及一個顯示區域。
程式中可以調整影像顯示的 Window/Level ,
並且有放大、拖曳(影像長寬超過顯示區域時)的功能,
此外顯示區域內會顯示影像的部份資訊。

程式下載位置︰http://code.google.com/p/dicomviewer/



Screenshot︰

Wednesday, March 25, 2009

MFC 多執行緒的鎖 - Lock

設計多執緒程式可以避免主程式執行工作時,被運算量較大的工作給絆住,造成視窗延遲的現象。但是在這樣的情況下,主程式的使用者可能會重複觸發程式中的子執行緒行程,使得同時有2個以上的相同子執行緒在工作。此外例如子執行緒工作尚未結束前,主程式的某某些特定工作時必須要等待子執緒的工作完成,程式該如何撰寫。類似的問題,可透過 Lock 來完成。

MFC 的 Lock 主要是由以下這幾項構成︰
CSemaphore mutex; // 全域變數,用來計數 lock 數
CSingleLock wait(&mutex); // 操作 lock 的類別
wait.Lock(INFINITE); // 要求鎖定 mutex
wait.Unlock(); // 要求解鎖 mutex

當程式嘗試呼叫 wait.Lock(INFINITE); 鎖定 mutex 時,若 mutex 已經在其他地方被鎖定,則程式在此處會停擺,直到其他地方解除鎖定。


#include "testview.h"
#include <>

CSemaphore mutex; // 宣告

UINT ChildThread_Function ( LPVOID param )
{
 CSingleLock wait(&mutex); // 操作 mutex 的類別
 wait.Lock(INFINITE); // 要求鎖定 mutex

 CTestView* view = (CTestView*) param;
 param->DoSomething();

 wait.Unlock(); // 要求解鎖 mutex
}

CTestView::DoSomething()
{
 ....
}

CTestView::Execute()
{
 AfxBeginThread( ChildThread_Function, (LPVOID) this, THREAD_PRIORITY_ABOVE_NORMAL); // 呼叫子執行緒
}

*************************************************************************************

若目的只要要求同一個 ChildTread 同一時間只能有一個執行,則可以使用較簡單的 Critical Section 方法。

CRITICAL_SECTION csObject; // 宣告為全域
InitialCriticalSection(&csObject); // 在主程式中初始化
EnterCriticalSection(&csObject); // 在ChildThread的開頭呼叫
LeaveCriticalSection(&csObject); // 在 ChildThread的結尾呼叫

#include "testview.h"
#include <>

CRITICAL_SECTION csObject; // 宣告

UINT ChildThread_Function ( LPVOID param )
{
 EnterCriticalSection(&csObject); // 鎖定

 CTestView* view = (CTestView*) param;
 param->DoSomething();

 LeaveCriticalSection(&csObject); // 解鎖
}

CTestView::CTestView()
{
 InitialCriticalSection(&csObject); // 初始化
}

CTestView::DoSomething()
{
 ....
}

CTestView::Execute()
{
 AfxBeginThread( ChildThread_Function, (LPVOID) this, THREAD_PRIORITY_ABOVE_NORMAL); // 呼叫子執行緒
}

簡單的 MFC 多執行緒寫法

一般程式的執行過程是一個指令一個指令逐步動作,當前一步指令尚未結束前,下一個指令就不會執行,這樣的操作是屬於單執行緒程式。
所謂多執行緒,則是程式在主要的執行緒之外,新增其他執行緒工作,使2個(或多個)執行緒同時進行工作,也稱為平行處理程式。
我的功力只算剛入門,充其量就是剛寫出一個有子執行緒的小程式,這裡做個筆記。

在 VC++ 所建立的 MFC 專案內,假設要加入子執行緒的地方在 testview.cpp 內 (類別為 CTestView,繼承自 CView)
如果要開啟子執行緒的函式為 CTestView::Execute() ,則:
#include "testview.h"

UINT ChildThread_Function ( LPVOID param )
{
 CTestView* view = (CTestView*) param;
 param->DoSomething();
}

CTestView::DoSomething()
{
 ....
}

CTestView::Execute()
{
 AfxBeginThread( ChildThread_Function, (LPVOID) this,  THREAD_PRIORITY_ABOVE_NORMAL);
}
ChildThread_Function 是全域函式,函式名稱由使用者自訂
AfxBeginThread 是MFC內呼叫子執行緒的方法,第一個參數是要執行的全域函式名稱(ChildThread_Function),第2個參數則是該全域函式的傳入值,此處傳入的是 CTestView 的指標。ChildThread_Function 這個子執行緒則是會呼叫 CTestView 的成員函式 DoSomething() 執行工作。

如果 ChildThread_Function 是 CTestView 的類別成員,則必須宣告為 static 才可以︰
class CTestView
{
 ..
 ..
 static UINT ChildThread_Function ( LPVOID param );
};

UINT CTestView::ChildThread_Function ( LPVOID param )
{
 ..
 ..
}