Microsoft KB Archive/269168

= How to recognize the difference among Excel 97 files, Excel 2000 files, and Excel 2002 files by using Visual C++ 6.0 =

Article ID: 269168

Article Last Modified on 1/27/2007

-

APPLIES TO


 * Microsoft Excel 2000 Standard Edition
 * Microsoft Excel 2002 Standard Edition
 * Microsoft Excel 97 Standard Edition
 * Microsoft Visual C++ 6.0 Professional Edition

-



This article was previously published under Q269168



SUMMARY
The Microsoft Excel 2000 file format and the Excel 2002 file format are the same as the Excel 97 file format with minor exceptions. One of the new additions to the Excel 2000 file format and to the Excel 2002 file format is a record that lets you detect when a file is saved with Excel 2000 or with Excel 2002 instead of with Excel 97. You use Microsoft Visual C++ 6.0 to detect the version of Excel that the file is saved with.



MORE INFORMATION
The record ID is 0x1C0. If this record is found in the Workbook stream, then the file is written by Excel 2000 or by Excel 2002. This is true unless the files is saved down for compatibility. Then, you can use code from the article that is mentioned in the &quot;References&quot; section to determine the version.

The following code demonstrates how this might be used: int IsExcel9(WCHAR *wcFilename) {

// Open document as an OLE compound document... HRESULT hr; IStorage *pStg = 0; hr = ::StgOpenStorage(wcFilename, 0, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStg); if(FAILED(hr)) return 0; // Now, get the Workbook stream IStream *pStm; WCHAR *wcBookStm = L&quot;Workbook&quot;; hr = pStg->OpenStream(wcBookStm, 0, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &pStm);

if(FAILED(hr)) { pStg->Release; return 0; }

char buf[32000]; DWORD dwRead; short id, len;

for { // Read id & len first... HRESULT hr = pStm->Read(&id, 2, &dwRead); if( (FAILED(hr)) || (dwRead != 2) ) break; pStm->Read(&len, 2, &dwRead); if(dwRead != 2) break; if((id == 0) && (len == 0)) break;

// Check for XL9File record if(id == 0x1c0) { pStm->Release; pStg->Release; return 1; }

// Eat record... if(len > 32000) len = 32000; pStm->Read(buf, (long)len, &dwRead); if((DWORD)len != dwRead) break; }

// Cleanup pStm->Release; pStg->Release; return 0; }

