明輝手游網(wǎng)中心:是一個免費提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺!

用IMAPI完成CD刻錄與設(shè)備搜索

[摘要]代碼下載:http://download.microsoft.com/download/1/6/4/164c2a20-aeb0-460f-907d-985d83e86bd4/CQA0404.exe MFC沒有提供CD刻錄的類,但WindowsXp內(nèi)置了寫入CD的支持。如果只是復(fù)制文件...
代碼下載:

http://download.microsoft.com/download/1/6/4/164c2a20-aeb0-460f-907d-985d83e86bd4/CQA0404.exe

        MFC沒有提供CD刻錄的類,但WindowsXp內(nèi)置了寫入CD的支持。如果只是復(fù)制文件和目錄,可以用shell's ICDBurn接口。如果要刻錄音頻或更近一步的實現(xiàn)對音頻的控制,那么下面會介紹一個專用的API。

        ICDBurn有三個方法,HasRecordableDrive掃描系統(tǒng)內(nèi)可寫的CD驅(qū)動器,找到的話返回TRUE。GetRecorderDriveLetter返回可寫驅(qū)動器的盤符。最后刻錄指令通知Windows從“集結(jié)區(qū)”向可寫CD拷貝數(shù)據(jù)。“集結(jié)區(qū)”是一個專用的文件夾,通常是"%userprofile%\Local Settings\Application Data\Microsoft\CD Burning", 但還是應(yīng)該調(diào)用SHGetFolderPath和參數(shù)CSIDL_CDBURN_AREA獲得準確的目錄名。開發(fā)者會經(jīng)常用到SHGetFolderPath,因為用戶會經(jīng)常手動或用PowerTools/TweakUI等工具改變刻錄的目錄。

        筆者寫了一個很短的類CCDBurn來封裝ICDBurn.這個結(jié)構(gòu)用CLSID_CDBurn調(diào)用CoCreateInstance,讀者可調(diào)試運行。

CCDBurn burner;

if (!burner.HasRecordableDrive()) {

   printf("Oops—No recordable drive!\n");

} else {

   CString dl =

       burner.GetRecorderDriveLetter();

   printf("Default Recorder drive letter =

       %s\n", (LPCTSTR)dl);

}



        驅(qū)動器盤符是在驅(qū)動器記錄屬性中啟動CD記錄功能的那個驅(qū)動器。只有一個驅(qū)動器可以設(shè)置這種屬性。假定HasRecordableDrive 返回TRUE,也就是電腦至少有一個可記錄的CD驅(qū)動器,你要做的就是把文件拷貝到集結(jié)區(qū)內(nèi),這就是刻錄。

        由于筆者很嚴謹,我又加入了另一個步驟GetBurnFolderPath,調(diào)用SHGetSpecialFolderPath 得到一個CString形式的刻錄文件目錄:

  CString path = burner.GetBurnFolderPath();

       如果要寫入音樂,或找到其他刻錄驅(qū)動器,或者獲得更詳細的信息:如驅(qū)動器是否是可寫的。對此,windows xp提供了IMAPI,它是Image Mastering API的縮寫,不要和 MAPI——用于e-mail的Messaging API 混淆。IMAPI提供了COM接口可以尋找可刻錄驅(qū)動器和寫入數(shù)據(jù)或者指向你最近用過的光驅(qū)。

       由于與COM的沖突會引起較大的問題,筆者寫了一個小的類庫,IMAPITools,解決了大多數(shù)問題。為了說明怎么用這個類庫筆者還寫了一個程序CDINFO。CDINFO在控制臺窗口中顯示CD記錄體的信息。

      只要掌握了IMAPI,CD刻錄就不難。但IMAPI很龐大,在講完基礎(chǔ)后再簡要的說一下這個問題。

      首先,CDINFO創(chuàng)建了一個對象顯示驅(qū)動器盤符和刻錄路徑。接著,創(chuàng)建CDiscMaster 打開IMAPI session:

   CDiscMaster dm; // create IDiscMaster

  if (!dm.Open()) {

     printf("Oops: ...");

     return;

CDiscMaster 封裝了第一個主IMAPI 接口IDiscMaster。它調(diào)用CoCreateInstance創(chuàng)建 Microsoft MSDiscMasterObj 對象然后得到IDiscMaster 接口。IDiscMaster 例舉出格式和記錄器,選擇活動記錄器等。

      CD分為兩種:記錄音頻的CD-Audio和存儲文件的CD-ROM。它們的格式分別為Redbook和Joliet。RedBook是Philips和Sony在80年代根據(jù)“redbook" 標(biāo)準制定的;Joliet是微軟擴展ISO-9660制定的一種CD-ROM文件格式。微軟在win95時代制定Joliet是為了擴展ISO-9660從而支持長文件名和多層目錄。

        IDiscMaster::EnumDiscMasterFormats可以例舉出刻錄器支持哪種格式,但是這種方法很耗費資源,我用一個簡單的方法實現(xiàn)了這個功能,CDiscMaster::GetSupportedFormats在數(shù)組IID中返回格式:

const MAXNFORMATS = 2;

IID fmts[MAXNFORMATS];

int nFormats = dm.GetSupportedFormats(fmts,MAXNFORMATS);

fmts數(shù)組中包含了支持的格式,IID_IRedbookDiscMaster和IID_IJoiletDiscMaster,而再也不用使用IEnumDiscMasterFormats了。有經(jīng)驗的程序員可能會提出疑問:為什么IMAPI的設(shè)計者選擇一個這么復(fù)雜的API來獲得只有兩種的支持格式,一行簡單的代碼就可以提供足夠的帶寬來傳送信息。這只有設(shè)計者知道答案,也許他們希望有人會用VB寫一個音頻記錄器。不管怎樣,只要你使用了IMAPITools,你就會忘記COM。

        一旦打開一個session,就可以實現(xiàn)查詢單個的刻錄驅(qū)動器。但IMAPI會再一次使用COM例舉刻錄器,而筆者又用一個類隱藏了這個結(jié)構(gòu)。

CDiscRecorder dr;

CDiscRecorderIterator itr(dm); // dm=CDiscMaster

while (itr.Next(dr)) {

// do something

}



        程序每次調(diào)用下一步,累加器就會抓取下一段記錄到CDiscRecorder中。CDiscRecorder封裝了其他大的IMAPI接口,CDiscRecorder代表了可記錄CD設(shè)備。CDiscRecorder提供了打開記錄器的方法,詢問它的類型(CD-R or CD-RW)和路徑,得到設(shè)備屬性,彈出CD等等。CDINFO演示了如何用CDiscRecorder獲得記錄器的所有信息。

        要把數(shù)據(jù)寫入光盤,就要使用IJolietDiscMaster或IRedbookDiscMaster,或者也可以用IMAPITools:

dm.SetActiveDiscRecorder(dr); // select recorder

CJolietDiscMaster jdm(dm); // get joliet interface

        jdm保存了IJolietDiscMaster接口,可以調(diào)用任何IJolietDiscMaster方法。AddData是寫入數(shù)據(jù)方法的一種;它需要一個COM IStorage指針。寫入音頻也是一樣的,除非是用IRedbookDiscMaster和AddAudioTrackBlocks 添加未處理的音頻數(shù)據(jù)(44.1 KHz, 16-bit RAW,  WAV 文件也相同)。創(chuàng)建多音軌可以用Create/CloseAudioTrack。AddData 和AddAudioTrackBlocks實際上不往光盤中寫數(shù)據(jù),而是寫到集結(jié)區(qū)中。如果要真正的移動數(shù)據(jù),還需要調(diào)用RecordDisc:

BOOL bSimulate=FALSE;

BOOL bEjectAfterBurn=TRUE;

dm.RecordDisc(bSimulate, bEjectAfterBurn);

dm.Close();

        bSimulate=TRUE會調(diào)用RecordDisc模擬刻錄但實際上并未寫入。Windows檢查全部預(yù)刻錄列表并刻錄,但實際上并沒有寫入。這可以讓開發(fā)者測試和調(diào)試軟件而并不需要花很多時間真正的刻錄光盤。

       以上簡單介紹了一下IMAPI,但這足夠你開始刻錄編程了。大多數(shù)人都會調(diào)用IMAPI,除非要寫一個復(fù)雜的備份程序或音頻紀錄器。對于普通的拷貝文件,要用到的就是ICDBurn。即使你要顯示出可記錄驅(qū)動器列表,用IMAPI也足夠了。