我们需要在使用Borlands Turbo C++开发的C\C++ Windows XP/Vista应用程序中以编程方式将文件刻录到CD.
这样做最简单,最好的方法是什么?我们更喜欢本机Windows API(不依赖于MFC),以便不依赖任何第三方软件/驱动程序(如果有的话).
我们使用了以下内容:
将文件存储在GetBurnPath返回的目录中,然后使用Burn编写.GetCDRecordableInfo用于检查CD何时就绪.
#include#include #include struct MEDIAINFO { BYTE nSessions; BYTE nLastTrack; ULONG nStartAddress; ULONG nNextWritable; ULONG nFreeBlocks; }; //============================================================================== // Description: CD burning on Windows XP //============================================================================== #define CSIDL_CDBURN_AREA 0x003b SHSTDAPI_(BOOL) SHGetSpecialFolderPathA(HWND hwnd, LPSTR pszPath, int csidl, BOOL fCreate); SHSTDAPI_(BOOL) SHGetSpecialFolderPathW(HWND hwnd, LPWSTR pszPath, int csidl, BOOL fCreate); #ifdef UNICODE #define SHGetSpecialFolderPath SHGetSpecialFolderPathW #else #define SHGetSpecialFolderPath SHGetSpecialFolderPathA #endif //============================================================================== // Interface IDiscMaster const IID IID_IDiscMaster = {0x520CCA62,0x51A5,0x11D3,{0x91,0x44,0x00,0x10,0x4B,0xA1,0x1C,0x5E}}; const CLSID CLSID_MSDiscMasterObj = {0x520CCA63,0x51A5,0x11D3,{0x91,0x44,0x00,0x10,0x4B,0xA1,0x1C,0x5E}}; typedef interface ICDBurn ICDBurn; // Interface ICDBurn const IID IID_ICDBurn = {0x3d73a659,0xe5d0,0x4d42,{0xaf,0xc0,0x51,0x21,0xba,0x42,0x5c,0x8d}}; const CLSID CLSID_CDBurn = {0xfbeb8a05,0xbeee,0x4442,{0x80,0x4e,0x40,0x9d,0x6c,0x45,0x15,0xe9}}; MIDL_INTERFACE("3d73a659-e5d0-4d42-afc0-5121ba425c8d") ICDBurn : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE GetRecorderDriveLetter( /* [size_is][out] */ LPWSTR pszDrive, /* [in] */ UINT cch) = 0; virtual HRESULT STDMETHODCALLTYPE Burn( /* [in] */ HWND hwnd) = 0; virtual HRESULT STDMETHODCALLTYPE HasRecordableDrive( /* [out] */ BOOL *pfHasRecorder) = 0; }; //============================================================================== // Description: Get burn pathname // Parameters: pathname - must be at least MAX_PATH in size // Returns: Non-zero for an error // Notes: CoInitialize(0) must be called once in application //============================================================================== int GetBurnPath(char *path) { ICDBurn* pICDBurn; int ret = 0; if (SUCCEEDED(CoCreateInstance(CLSID_CDBurn, NULL,CLSCTX_INPROC_SERVER,IID_ICDBurn,(LPVOID*)&pICDBurn))) { BOOL flag; if (pICDBurn->HasRecordableDrive(&flag) == S_OK) { if (SHGetSpecialFolderPath(0, path, CSIDL_CDBURN_AREA, 0)) { strcat(path, "\\"); } else { ret = 1; } } else { ret = 2; } pICDBurn->Release(); } else { ret = 3; } return ret; } //============================================================================== // Description: Get CD pathname // Parameters: pathname - must be at least 5 bytes in size // Returns: Non-zero for an error // Notes: CoInitialize(0) must be called once in application //============================================================================== int GetCDPath(char *path) { ICDBurn* pICDBurn; int ret = 0; if (SUCCEEDED(CoCreateInstance(CLSID_CDBurn, NULL,CLSCTX_INPROC_SERVER,IID_ICDBurn,(LPVOID*)&pICDBurn))) { BOOL flag; WCHAR drive[5]; if (pICDBurn->GetRecorderDriveLetter(drive, 4) == S_OK) { sprintf(path, "%S", drive); } else { ret = 1; } pICDBurn->Release(); } else { ret = 3; } return ret; } //============================================================================== // Description: Burn CD // Parameters: None // Returns: Non-zero for an error // Notes: CoInitialize(0) must be called once in application //============================================================================== int Burn(void) { ICDBurn* pICDBurn; int ret = 0; if (SUCCEEDED(CoCreateInstance(CLSID_CDBurn, NULL,CLSCTX_INPROC_SERVER,IID_ICDBurn,(LPVOID*)&pICDBurn))) { if (pICDBurn->Burn(NULL) != S_OK) { ret = 1; } pICDBurn->Release(); } else { ret = 2; } return ret; } //============================================================================== bool GetCDRecordableInfo(long *FreeSpaceSize) { bool Result = false; IDiscMaster *idm = NULL; IDiscRecorder *idr = NULL; IEnumDiscRecorders *pEnumDiscRecorders = NULL; ULONG cnt; long type; long mtype; long mflags; MEDIAINFO mi; try { CoCreateInstance(CLSID_MSDiscMasterObj, 0, CLSCTX_ALL, IID_IDiscMaster, (void**)&idm); idm->Open(); idm->EnumDiscRecorders(&pEnumDiscRecorders); pEnumDiscRecorders->Next(1, &idr, &cnt); pEnumDiscRecorders->Release(); idr->OpenExclusive(); idr->GetRecorderType(&type); idr->QueryMediaType(&mtype, &mflags); idr->QueryMediaInfo(&mi.nSessions, &mi.nLastTrack, &mi.nStartAddress, &mi.nNextWritable, &mi.nFreeBlocks); idr->Release(); idm->Close(); idm->Release(); Result = true; } catch (...) { Result = false; } if (Result == true) { Result = false; if (mtype == 0) { // No Media inserted Result = false; } else { if ((mflags & 0x04) == 0x04) { // Writable Media Result = true; } else { Result = false; } if (Result == true) { *FreeSpaceSize = (mi.nFreeBlocks * 2048); } else { *FreeSpaceSize = 0; } } } return Result; }