• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            醬壇子

            專注C++技術(shù) 在這里寫下自己的學習心得 感悟 和大家討論 共同進步(歡迎批評!!!)

              C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
              66 Posts :: 16 Stories :: 236 Comments :: 0 Trackbacks

            公告

            王一偉 湖南商學院畢業(yè) 電子信息工程專業(yè)

            常用鏈接

            留言簿(19)

            我參與的團隊

            搜索

            •  

            積分與排名

            • 積分 - 387837
            • 排名 - 64

            最新隨筆

            最新評論

            閱讀排行榜

            評論排行榜

            小弟想實現(xiàn)將硬盤某個文件夾下的文件刻錄到光盤上

            我不想使用第三方的刻錄軟件

            不知道XP系統(tǒng)是否有提供這樣的接口,哪位大蝦知道請給小弟一點提示:)給個思考的方向就可以了

            謝過了
            posted on 2006-10-30 11:41 @王一偉 閱讀(1664) 評論(5)  編輯 收藏 引用

            Feedback

            # re: 求實現(xiàn)方法!! 2006-10-30 12:07 CornerZhang
            XP是自帶這個功能的,我的是English版,只要“IMAPI CD-Burning COM Service”這個系統(tǒng)服務(wù)開著,就可以的。怎么用你google一下吧  回復(fù)  更多評論
              

            # re: 求實現(xiàn)方法!! 2006-10-30 12:22 王一偉
            <轉(zhuǎn):在網(wǎng)上看見的別人寫的東西>


            關(guān)于使用IMAPI的一些問題
            工作中要求使用IMAPI寫一個小的刻錄測試程序,苦于資料較少,但最后大體理出一些內(nèi)容,并初步測試通過,把一些心得和問題記錄在此。希望交流一下。程序基于MSDN (April 2004)和微軟工程師Paul DiLascia的一個例程,并作了一定修改,環(huán)境是XPsp2和VS.net2003(MFC)。

            1.IDiscMaster::ProgressAdvise()的使用
            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // 聲明一個類,從接口繼承
            class CDiscMasterProgressEvents : public CComQIPtr<IDiscMasterProgressEvents>
            {
            public:
            HRESULT m_hr;
            int m_nRefCount;

            // 進度條控件
            CProgressCtrl * m_pCtlProgress;

            // 構(gòu)造和析構(gòu)
            CDiscMasterProgressEvents(/*CWnd * pWnd*/);

            ULONG __stdcall AddRef(void);
            ULONG __stdcall Release(void);
            HRESULT __stdcall QueryInterface(REFIID riid, void **ppv);

            // 以下為一些消息的回調(diào)函數(shù)
            // 刻錄結(jié)束后被IMAPI調(diào)用(Reports that the burn is fully complete.IDiscMaster::RecordDisc()結(jié)束時調(diào)用)
            HRESULT __stdcall NotifyBurnComplete(HRESULT status);

            .............................
            };

            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //類實現(xiàn)代碼
            ULONG __stdcall CDiscMasterProgressEvents::AddRef(void)
            {
            return ++m_nRefCount;
            }

            ULONG __stdcall CDiscMasterProgressEvents::Release(void)
            {
            if (--m_nRefCount)
            return m_nRefCount;
            delete this;
            return 0L;
            }

            HRESULT __stdcall CDiscMasterProgressEvents::QueryInterface(REFIID riid, void **ppv)
            {
            if(riid == IID_IUnknown)
            {
            *ppv = (LPUNKNOWN)(IDiscMasterProgressEvents*)this;
            m_nRefCount++;
            return NOERROR;
            }
            else if(riid == IID_IDiscMasterProgressEvents)
            {
            *ppv = (IDiscMasterProgressEvents*)this;
            m_nRefCount++;
            return NOERROR;
            }
            else
            {
            *ppv = NULL;
            return E_NOINTERFACE;
            }
            }

            // 刻錄結(jié)束后被IMAPI調(diào)用
            HRESULT __stdcall CDiscMasterProgressEvents::NotifyBurnComplete(HRESULT status)
            {
            if (status == S_OK)
            {
            AfxMessageBox("刻錄完畢");
            if (m_pCtlProgress)
            {
            m_pCtlProgress->SetPos(0);
            }
            }
            return status ;
            }
            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // 類的使用
            ..........

            CDiscMasterProgressEvents * pEvent = new CDiscMasterProgressEvents;
            pEvent->m_pCtlProgress = &(pDlg->m_progBurning);
            UINT_PTR m_nCookie = 0;

            // dm為CDIscMater(class CDiscMaster : public CComQIPtr<IDiscMaster>)
            hr = dm.ProgressAdvise(pEvent, &m_nCookie); // ok

            ..........
            hr = dm.RecodeDisc(0, 0);

            2. IJolietDiscMaster::AddData()前,所有IStream.Release()和子ISubStorage.Release();
            如果沒有釋放,我遇到的問題是數(shù)據(jù)刻錄到光盤中,但卻看不到;根IStorage在AddData后Release()

            3.文件名和文件夾名的問題
            pStorage->CreateStream(const WCHAR* pwcsName, ....); // 參數(shù)對應(yīng)刻錄后的文件名
            pStorage->CreateStorage(const WCHAR* pwcsName, .....); // 參數(shù)對應(yīng)刻錄后的子文件夾名
            上面的兩個參數(shù)都不能超過31個字符,不能使用某些特殊字符(!等),否則會造成創(chuàng)建失敗;沒有查到資料如何處理超過31字符的文件名,如果有解決問題的方法,希望能和大家交流。

            4.光盤的Volume(沒有測試)
            通過IJolietDiscMaster::GetJolietProperties()得到;對應(yīng)的一個IJolietDiscMaster::SetJolietProperties()

            5.IDiscRecorder::GetPath(BSTR* pbstrPath)(未解決)
            得到刻錄機路徑,MSDN說明:
            Parameters
            pbstrPath
            [out] Path to the disc recorder. This can be a drive letter such as 'E:\', or a full path such as '\Device\CdRom0'.
            測試程序中得到的是后者,還沒有找到合理的方式來把兩者掛鉤,特別是多光驅(qū)情況下
              回復(fù)  更多評論
              

            # re: 求實現(xiàn)方法!! 2006-10-30 12:23 王一偉
            @CornerZhang
            多謝了,我查到的也是這個  回復(fù)  更多評論
              

            # re: 求實現(xiàn)方法!! 2006-10-30 12:25 王一偉
            http://download.microsoft.com/download/1/6/4/164c2a20-aeb0-460f-907d-985d83e86bd4/CQA0404.exe

            用IMAPI實現(xiàn)CD刻錄和設(shè)備查找

            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" 標準制定的;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也足夠了。
              回復(fù)  更多評論
              

            # re: 求實現(xiàn)方法!! 2006-10-30 13:53 王一偉
            注意必須在服務(wù)管理器中開啟IMAPI CD-Burning COM Service服務(wù)  回復(fù)  更多評論
              


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            一本久久a久久精品综合夜夜| 久久66热人妻偷产精品9| 国产精品嫩草影院久久| 国产AV影片久久久久久| 人人狠狠综合88综合久久| 国产精品美女久久福利网站| 日本人妻丰满熟妇久久久久久| 久久婷婷国产综合精品| 久久久久亚洲AV无码去区首| 久久久久久曰本AV免费免费| 国产午夜精品理论片久久影视| 狠狠久久综合伊人不卡| 久久久久久九九99精品| 精品国产91久久久久久久a| 无码人妻少妇久久中文字幕蜜桃| 99久久国产综合精品网成人影院| 精品综合久久久久久98| 久久免费99精品国产自在现线 | 久久综合久久自在自线精品自| 久久精品国产免费| 国色天香久久久久久久小说| 国产精品狼人久久久久影院 | 久久精品国产亚洲麻豆| 久久久亚洲AV波多野结衣| 亚洲国产精品久久久久网站| 久久亚洲精品人成综合网| 日本欧美国产精品第一页久久| 色成年激情久久综合| 久久婷婷激情综合色综合俺也去| 亚洲精品成人久久久| 久久久久人妻精品一区三寸蜜桃| 欧美一区二区精品久久| 久久精品无码一区二区三区| 久久丫精品国产亚洲av| 国产激情久久久久久熟女老人| 一极黄色视频久久网站| 亚洲伊人久久综合中文成人网| 无码乱码观看精品久久| 亚洲欧美成人久久综合中文网 | 久久婷婷五月综合97色一本一本| 久久久高清免费视频|