2008年8月18日 星期一

使用全域熱鍵(Global hotkey)在VB .NET

這篇文章是介紹如何使用VB 2005來編寫可以讀取全域熱鍵(foobar翻成整體熱鍵)的程式,如果你是要找怎麼利用整體熱鍵,那很抱歉你可能迷路了XXD。
在開始寫程式之前,先來稍微介紹一下整體熱鍵的運作方式。
如左圖所示,一般來說,鍵盤上面的訊號是先送給OS處理後,經過管理程序再送給目前活動中(in active)的程序;所以當程式並不是在活動中,那麼自然就不會接收到目前鍵盤的訊號。
而全域熱鍵的用處就在於即使我的程式已經是在背景中,假如鍵盤有相對應的鍵被按下,我的程式也能夠做出想要的回應。而在XP系統下,提供了一個動態函式庫來讓我得以達成以上的需求:user32.dll。我可以藉由user32.dll向管理程序去通知說,我也要接收某些特定的鍵盤訊號,不論我是不是在活動中。註冊完畢後,當鍵盤有訊號進來,管理程序就會看目前進來的訊號是不是有人註冊過,如果有,這個值除了會丟給目前活動中的程序,也會丟給我註冊過的程序。
打個比方好了,就像是像在很常見的網路促銷活動,在一般的情況下如果要知道某商家有沒有特價或是促銷,只能透過商家固定的廣告來得到該資訊,或是要直接到賣場去才能看到。這就是一般的模式下情況,只有固定的一些程序(像是活動中的程序)才能獲得目前鍵盤的資訊。而假如我加入商家的會員,或是到他們的網站上去註冊,那麼就只要打開email(或是實體信箱),就可以知道商家最近有沒有什麼新的特價方案,就只要等著商家就會把訊息傳過來。我的程序也是一樣,一但完成了註冊的動作,負責管理鍵盤訊號的程序就會在有我所觀察的把訊發生之後,一並通知我。
所以在程式的一開始,我必須做這兩行的宣告:
Private Declare Function RegisterHotKey Lib "user32" (ByVal hwnd As IntPtr, ByVal id As Integer, ByVal fsModifiers As Integer, ByVal vk As Integer) As Integer
Private Declare Sub UnregisterHotKey Lib "user32" (ByVal hwnd As IntPtr, ByVal id As Integer)
告訴程式說,在接下來的程式碼中我需要這兩個從user32函式庫中的函式。
接下來的步驟比較繁複一點,須要參看程式碼,不過部落格中的空白都會被清空,內縮的格式會跑掉變得很難看,所以程式碼就貼在google文件中,連結在這
從form load開始看起,可以看到其中只有一行程式碼,裡面寫的是RegisterGlobalHotKey這個函式,目的是完成整個註冊全域熱鍵的動作,如果懶的去改直接就整個抓去用。比較要注意的是,取得hotkeyID的atomName,原程式碼中是利用threadID去做,不過用這麼麻煩的東西是可以用拉~。而其中 GlobalAddAtom函式就是取得一個類是hash code的東西,他會在系統的atom table寫入原字串以及獲得的atom(類似hash後的key值),在此程式中是利用此函式來得到用來註冊的hotkeyID值。
從form load上面一點看,會看到許多常數的宣告,那些是代表alt, shift, ctrl之類的鍵,不用做任何改變就可以。然後既然有註冊hotkey,當然也要有反註冊的函式UnregisterHotKey,當我們程式要結束的時候通知一下,這個程式已經死掉拉~~不要再寄訊息過來了。所以就照著程式碼那樣把反註冊函式寫完整在UnregisterGlobalHotKey,然後補在form closed(或是closing都可)裡面,讓程式結束後可以把hotkey反註冊掉。
接下來就是最重要的地方拉,如果要讓全域鍵按下後程式有所反應,程式碼就要寫在WndProc裡面。這個函式主要是接收從其他程序丟過來的訊息,所以當丟過來的訊息使說有使用者按下了我所設定的全域鍵,那麼就要給他好好處理一下拉。如果有要在全域熱鍵按下後所執行的程式碼,那麼就要寫在If m.Msg = WM_HOTKEY的裡面。在這個範例中,只做了一個計數器,來計算全域熱鍵被按下幾次,並且在全域熱鍵按下後,將自己設定為活動中的狀態。
這篇就寫到這樣吧,如果要加入全域熱鍵,直接把整篇程式碼給加進去其實也就差不多了XXD,只要把一些地方給改變一下,像是全域熱鍵的設定、按下熱鍵後的處理等比較重要的地方改一下,就可以用了。
在網路上還有找到另外一種做法,一樣是利用user32這個函式庫,又興趣的人可以參考一下^^。
參考網址:
http://www.codeguru.com/vb/gen/vb_system/keyboard/article.php/c4829/
http://www.vbforums.com/showthread.php?t=506461

2008年8月10日 星期日

將音樂檔案轉換成TAK格式

ㄐㄧㄤ~因為上一篇聆聽TAK音樂檔案看起來增加了不少點擊數,所以就先把這篇給補起來吧。^^
其實要將檔案轉換成TAK其實還蠻簡單的,首先到TAK的官網下載最新版本的編碼器(encoder)。目前最新的版本(打這篇文章的時候)是1.0.4
下載解壓縮,可以發現有幾個資料夾:
  • Applications
  • Deco_Lib
  • Sdk
  • Winamp
而要編碼須要用的只有Applications資料夾內的東西,其他就參看Contents.txt裡面的解說,其中有寫各資料夾內含物是什麼。
在這裡利用foobar2000配合takc.exe來進行轉檔,foobar真是個不錯的東西阿,不但可以拿來聽音樂,支援多種音樂格式,也可以透過各種不同音樂的編碼器來對音樂檔案進行轉檔。把在剛剛解壓縮後的資料夾Applications內的takc給複製到foobar資料夾下(這樣以後管理編碼器可能會比較方便),這樣檔案的準備工作也就可以說是完成了,等等就要開始參數的設定工作。
  1. 打開foobar後,選擇Preferences,然後在Tool中選擇Converter。
  2. 在Converter畫面的中間有個Encodeng Presets,在其右邊選擇Add New。
  3. 最上方的Encoder選擇custom,而接下來那個encoder則是編碼器的路徑,在這邊是Takc.exe的路徑。Extention則填入tak;Parameters請填入-e -ihs -p2 -overwrite - %d;中間那bit depth control不用管,用預設值即可;Encoder name當然就填入TAK,setting就填normal吧。
  4. 在播放清單中,對想要轉檔的檔案按下滑鼠右鍵,選擇convert=>convert to=>在encoding preset挑選 TAK normal就可以把該音樂檔轉成TAK格式。
知到了該怎麼去設定參數,那麼也應該了解一下參數所代表的意義。我們這邊用的參數是:-e -ihs -p2 -overwrite - %d。其中-e是代表我們是要對檔案編碼;-ihs是要給多執行緒用的特殊指令;-p2是壓縮比的模式;-overwrite是直接複寫掉已存在的檔案;%d是foobar給的檔案名稱。

這邊比較重要的是壓縮模式,tak總共提供了6種不同程度的壓縮,由p0到p5壓縮比越來越大,壓縮所需要的時間也越長;另外每個不同的程式還提供了該程度的最大壓縮m,與該程度較高壓縮的e,像是p1的最大就是p1m、較高就是p1e,p2最大就是p2m、較高就是p2e,p5最大則是p5m,也是所有壓縮比中最高的,也可以用pMax來表示。所以6種不同的程度再加上每個壓縮程度還擁有一個max與Extra,所以全部共有18種不同壓縮的比率。雖然官方所認定的noraml是p2,不過記然要壓縮當然要壓最高,所以一般在使用還是會設定到pMax,雖然在編碼的時候需要多花點時間,不過壓縮比還算高,而且也比ape的解碼速度還要來的快。

除了使用foobar配合takc之外,也可以直接使用官方所提供的壓縮解壓縮軟體,與takc同一資料夾內的tak.exe。操作也不難,選擇compress(壓縮)後,把要壓縮的檔案(wav檔)加入,並在option設定好一些參數就可以了。不過因為只支援wav檔,基本上還是foobar來的方便。

這邊也有教學,只要會一些簡單的英文就可以看得懂,如果是使用EAC的人可以去參考看看,這邊因為沒有玩過EAC所以就不寫了~。

p.s. 這篇東西老實說寫的我很灰心,怎麼寫都沒辦法合我的意,寫出來的東西有點...如果有人能夠提一些如何改進這篇文章的意見我會很開心的XD。