• <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ù) 在這里寫下自己的學(xué)習(xí)心得 感悟 和大家討論 共同進(jìn)步(歡迎批評(píng)!!!)

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

            公告

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

            常用鏈接

            留言簿(19)

            我參與的團(tuán)隊(duì)

            搜索

            •  

            積分與排名

            • 積分 - 387222
            • 排名 - 64

            最新隨筆

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

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

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

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

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

            Feedback

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

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


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

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

            // 進(jìn)度條控件
            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é)束時(shí)調(diào)用)
            HRESULT __stdcall NotifyBurnComplete(HRESULT status);

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

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

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

            5.IDiscRecorder::GetPath(BSTR* pbstrPath)(未解決)
            得到刻錄機(jī)路徑,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'.
            測(cè)試程序中得到的是后者,還沒有找到合理的方式來把兩者掛鉤,特別是多光驅(qū)情況下
              回復(fù)  更多評(píng)論
              

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

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

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

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

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

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

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

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

            CString path = burner.GetBurnFolderPath();

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

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

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

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

            CDiscMaster dm; // create IDiscMaster

            if (!dm.Open()) {

            printf("Oops: ...");

            return;

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

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

            IDiscMaster::EnumDiscMasterFormats可以例舉出刻錄器支持哪種格式,但是這種方法很耗費(fèi)資源,我用一個(gè)簡單的方法實(shí)現(xiàn)了這個(gè)功能,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)驗(yàn)的程序員可能會(huì)提出疑問:為什么IMAPI的設(shè)計(jì)者選擇一個(gè)這么復(fù)雜的API來獲得只有兩種的支持格式,一行簡單的代碼就可以提供足夠的帶寬來傳送信息。這只有設(shè)計(jì)者知道答案,也許他們希望有人會(huì)用VB寫一個(gè)音頻記錄器。不管怎樣,只要你使用了IMAPITools,你就會(huì)忘記COM。

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

            CDiscRecorder dr;

            CDiscRecorderIterator itr(dm); // dm=CDiscMaster

            while (itr.Next(dr)) {

            // do something

            }



            程序每次調(diào)用下一步,累加器就會(huì)抓取下一段記錄到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ù)方法的一種;它需要一個(gè)COM IStorage指針。寫入音頻也是一樣的,除非是用IRedbookDiscMaster和AddAudioTrackBlocks 添加未處理的音頻數(shù)據(jù)(44.1 KHz, 16-bit RAW, WAV 文件也相同)。創(chuàng)建多音軌可以用Create/CloseAudioTrack。AddData 和AddAudioTrackBlocks實(shí)際上不往光盤中寫數(shù)據(jù),而是寫到集結(jié)區(qū)中。如果要真正的移動(dòng)數(shù)據(jù),還需要調(diào)用RecordDisc:

            BOOL bSimulate=FALSE;

            BOOL bEjectAfterBurn=TRUE;

            dm.RecordDisc(bSimulate, bEjectAfterBurn);

            dm.Close();

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

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

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


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


            精品无码人妻久久久久久| 久久人人爽人人澡人人高潮AV| 久久久国产精品| 久久93精品国产91久久综合| 精品亚洲综合久久中文字幕| 国内精品久久久久影院优| 精品久久久久中文字幕日本| 久久人妻少妇嫩草AV无码专区| 亚洲AV日韩精品久久久久久| 无码人妻久久一区二区三区免费丨 | 国产成人精品免费久久久久| 色欲久久久天天天综合网| 久久婷婷五月综合国产尤物app| 一本一道久久综合狠狠老| 精品久久久久久中文字幕人妻最新| 久久国产精品国产自线拍免费| 94久久国产乱子伦精品免费| 久久亚洲天堂| 亚洲第一极品精品无码久久| 亚洲国产精品久久| 亚洲精品综合久久| 国内精品久久人妻互换| 久久久久亚洲AV综合波多野结衣 | 久久精品99久久香蕉国产色戒 | 国产69精品久久久久久人妻精品| 亚洲精品乱码久久久久66| 99久久精品国内| 天天综合久久一二三区| 久久国产乱子伦免费精品| 精品久久久无码中文字幕| 亚洲精品国产第一综合99久久| 精品国产一区二区三区久久久狼 | 国产精品99久久久久久www| 午夜视频久久久久一区 | 久久99这里只有精品国产| 久久午夜伦鲁片免费无码| 精品国产乱码久久久久久浪潮 | 伊人久久一区二区三区无码| 国内精品久久久久影院优| 国产精品乱码久久久久久软件| 青草影院天堂男人久久|