I debugged XTP. There is MAJOR bug in implementation of XTP. It can read the customization ONLY from registry. It always fails to read from file because of the bug in CXTPZipMemFile when compiled with MFC6.0
void CXTPCommandBars::LoadBarState(LPCTSTR lpszProfileName, BOOL bSilent) {
XTP_COMMANDBARS_PROPEXCHANGE_PARAM paramT; paramT.pCommandBars = this; paramT.bLoadSilent = bSilent;
if (m_bCustomizeAvail) { TCHAR szSection[256]; wsprintf(szSection, _xtpCommandBarControlsSection, lpszProfileName);
if (AfxGetApp()->GetProfileInt(szSection, _xtpCommandBarLoadFromFile, FALSE)) { CString strFileName = AfxGetApp()->GetProfileString(szSection, _xtpCommandBarControls); CXTPZipMemFile file; if (file.OpenCompressedFile(strFileName)) { _LoadControlsPart(file, ¶mT); <--- HERE IT FAILS TO READ ANY DATA BECAUSE OF THE FACT THAT THERE IS A MAJOR BUG IN CXTPZipMemFile ! }
}
What bug is in CXTPZipMemFile ?
Let's look:
class CXTPZipMemFile : public CMemFile {
...
BOOL OpenCompressedFile(LPCTSTR lpszFileName) { if (!CFile::Open(lpszFileName, CFile::modeRead)) return FALSE;
UINT nSize = (UINT)CFile::GetLength(); // PUT A BREAKPOINT HERE AND YOU WILL FIND THAT SIZE REPORTED HERE IS ALWAYS ZERO !!! LPBYTE lpBuffer = (LPBYTE)malloc(nSize); CFile::Read(lpBuffer, nSize);
CFile::Close();
AttachCompressedBuffer(lpBuffer, nSize, TRUE);
return TRUE; }
The bug is that the size reported in the line marked above is always zero because the code actually checks CMemFile (that is NOT initalized), not the underlying physical file. This is due to the implementation differences between MFC 6.0 (that I am using and XTP is compatible with) and MFC 8.0 (that apparently Codejock is using for "testing")
MFC 6.0 GetLength():
DWORD CFile::GetLength() const { ASSERT_VALID(this);
DWORD dwLen, dwCur;
// Seek is a non const operation CFile* pFile = (CFile*)this; dwCur = pFile->Seek(0L, current); dwLen = pFile->SeekToEnd(); VERIFY(dwCur == (DWORD)pFile->Seek(dwCur, begin));
return dwLen; }
MFC 8.0 GetLength():
ULONGLONG CFile::GetLength() const { ASSERT_VALID(this);
ULARGE_INTEGER liSize; liSize.LowPart = ::GetFileSize(m_hFile, &liSize.HighPart); if (liSize.LowPart == INVALID_FILE_SIZE) if (::GetLastError() != NO_ERROR) CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName);
return liSize.QuadPart; }
Problem is that MFC6.0 will report ZERO size for uninitalized memfile inside CXTPZipMemFile instead of correct physical file size. This makes CXTPZipMemFile useless if compiled with MFC6.0 - it simply does not work at all and any application using it will fail (including loading customization data from external files).
Solution: inside CXTPZipMemFile don't use CFile::GetLength().
Instead use Windows API ULARGE_INTEGER liSize; liSize.LowPart = ::GetFileSize(m_hFile, &liSize.HighPart);
There are other bugs in the library too, I guess that someone at codejock did not do their homework.
|