关于使用IMAPI的一些问题

本文分享了使用IMAPI开发刻录测试程序的经验,重点介绍了IDiscMaster::ProgressAdvise()的使用方法,包括进度反馈机制及回调函数的实现。同时讨论了IJolietDiscMaster::AddData()前资源释放的重要性,文件名限制等问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       工作中要求使用IMAPI写一个小的刻录测试程序,苦于资料较少,但最后大体理出一些内容,并初步测试通过,把一些心得和问题记录在此。希望交流一下。程序基于MSDN (April 2004)和微软工程师Paul DiLascia的一个例程,并作了一定修改,环境是XPsp2和VS.net2003(MFC)。

1.IDiscMaster::ProgressAdvise()的使用
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 声明一个类,从接口继承
class CDiscMasterProgressEvents : public CComQIPtr<IDiscMasterProgressEvents>
{
public:
       HRESULT m_hr;
       int m_nRefCount;
 
      // 进度条控件
      CProgressCtrl * m_pCtlProgress;
 
      // 构造和析构
      CDiscMasterProgressEvents(/*CWnd * pWnd*/);
 
      ULONG __stdcall AddRef(void);
      ULONG __stdcall Release(void);
      HRESULT __stdcall QueryInterface(REFIID riid, void **ppv);
 
       // 以下为一些消息的回调函数 
       // 刻录结束后被IMAPI调用(Reports that the burn is fully complete.IDiscMaster::RecordDisc()结束时调用)
       HRESULT __stdcall NotifyBurnComplete(HRESULT status);
 
       .............................
 };
 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //类实现代码
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;
     }
}
 
// 刻录结束后被IMAPI调用
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);
 
2IJolietDiscMaster::AddData()前,所有IStream.Release()和ISubStorage.Release();
如果没有释放,我遇到的问题是数据刻录到光盘中,但却看不到;根IStorage在AddData后Release()
 
3.文件名和文件夹名的问题
pStorage->CreateStream( const WCHAR* pwcsName , ....);  // 参数对应刻录后的文件名
pStorage->CreateStorage( const WCHAR* pwcsName , .....); // 参数对应刻录后的子文件夹名
上面的两个参数都不能超过31个字符,不能使用某些特殊字符(!等),否则会造成创建失败;没有查到资料如何处理超过31字符的文件名,如果有解决问题的方法,希望能和大家交流。
 
4.光盘的Volume(没有测试)
通过IJolietDiscMaster::GetJolietProperties()得到;对应的一个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'.
测试程序中得到的是后者,还没有找到合理的方式来把两者挂钩,特别是多光驱情况下

我的邮箱label_2000@sina.com,可以把我的测试代码发给你, 希望能多多交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值