我读了你在 January 2004 中有关获取驱动器盘符以及用 GetDriveType 函数判定某个磁盘是否为 CD(DRIVE_CDROM)的专栏文章,但我如何才能知道 CD 驱动器是不是刻录设备呢?此外,如何将文件写入可擦写 CD?Windows XP 允许你用 Windows 资源管理拖拽文件,并将其写入CD。你能否告知有没有什么方法从我的程序中实现,而不需要用户购买第三方软件,如:Nero 或者 Roxio? 有没有相关的 MFC 类可以实现这个功能?
MFC 没有提供 CD 刻录的类,但 Windows Xp 内置了写入 CD 的支持。如果只是复制文件和目录,可以用 shell''s ICDBurn 接口。如果要刻录音频或更近一步的实现对音频的控制,那么下面会介绍一个专用的 API。
用 ICDBurn 有三个步骤,HasRecordableDrive 扫描系统内可写的CD驱动器,找到的话返回TRUE。GetRecorderDriveLetter 返回可写驱动器的盘符。最后刻录指令通知 Windows 从“集结区”向可写 CD 拷贝数据。“集结区”是一个专用的文件夹,通常是“%userprofile%\Local Settings\Application Data\Microsoft\CD Burning”,但还是应该调用 SHGetFolderPath 和参数 CSIDL_CDBURN_AREA 获得准确的目录名。开发者会经常用到 SHGetFolderPath,因为用户会经常手动或用 PowerTools/TweakUI 等工具改变刻录的目录。
笔者写了一个很短的类 CCDBurn 来封装 ICDBurn。这个结构用 CLSID_CDBurn 调用 CoCreateInstance,读者可调试运行。
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);
}
驱动器盘符是在驱动器记录属性中启动CD记录功能的那个驱动器。只有一个驱动器可以设置这种属性。假定 HasRecordableDrive 返回TRUE,也就是电脑至少有一个可记录的CD驱动器,你要做的就是把文件拷贝到集结区内,这就是刻录。
由于笔者很严谨,我又加入了另一个步骤 GetBurnFolderPath,调用 SHGetSpecialFolderPath 得到一个 CString 形式的刻录文件目录:
CString path = burner.GetBurnFolderPath();
Figure 1 CD 驱动的刻录属性
如果你想刻录音乐,或找到其它刻录驱动器(可能有多个),或者获得更详细的信息:如制造或型号,或者驱动器是 CD-R 还是 CD-RW?为此,Windows XP 提供了 IMAPI 来实现这些特性,它是 Image Mastering API 的缩写,不要和 MAPI——用于 e-mail 的 Messaging API 混淆。唉!要记住这些缩写真是难啊。IMAPI 提供了 COM 接口来寻找可刻机驱动器和写入数据,或者最新射频探头调谐到光光彩照人的塑胶唱盘上。有关 IMAPI 接口信息概要参见 Figure 2。
由于与 COM 的冲突会引起较大的问题,笔者写了一个小的类库,IMAPITools,解决了大多数问题。为了说明怎么用这个类库笔者还写了一个程序 CDINFO。CDINFO 在控制台窗口中显示CD记录体的信息。
只要掌握了 IMAPI,CD,刻录就不难。但 IMAPI 很庞大,在讲完基础后再简要的说一下这个问题。
Figure 3 CDINFO
首先,CDINFO创建了一个对象显示驱动器盘符和刻录路径。接着,创建 CDiscMaster 打开IMAPI session:
CDiscMaster dm; // create IDiscMaster
if (!dm.Open()) {
printf("Oops: ...");
return;
}