Why 11.2 breaks compatibility with LoadCommandBars |
Post Reply |
Author | |
Tomasz
Senior Member Joined: 05 August 2006 Status: Offline Points: 109 |
Post Options
Thanks(0)
Posted: 04 October 2007 at 5:31pm |
Hello,
One of my applications was using XTP 9.81 and it worked fine. Command bar customizations were written to file and restored just fine. Now after upgrade to 11.4 LoadCommandBars fails to load command bar customizations! As it turns out there is some magic key in registry (NOT DOCUMENTED that controls the process (ProfileName-Options/LoadFromFile). By default it is set to zero and this means that user settings/customizations are LOST. I tried to switch to 1 but then code breaks. Codejock - this is sick ! Why don't you keep backward compatiblity for user created files and why do you break such basic functions like LoadCommandBars????
I want to load old data. My customers are extremely frustrated when they lose old settings. Now tell me how should I load all command bar customizations. My customers have to load old data. This is cruicial. I am paying customer, supporting you for 3 years. I am going to stop supporting XTP if you break the code that way.
Tomasz
|
|
Tomasz
Senior Member Joined: 05 August 2006 Status: Offline Points: 109 |
Post Options
Thanks(0)
|
Update: the Options/LoadFromFile key was generated and used by 9.81 too but new version of the library (11.2) does not load properly data created with previous version.
Also there is a problem with saving command bar customizations in 11.2 alone!
For example if you add new button to the toolbar it is stored OK.
BUT....
if you have combo box and RESIZE it during customization - this new change is NOT saved.
I also tried with SAMPLE applications and it turns out that there is a bug in 11.2 that prevents from saving resized combo-boxes placed in command bars. You can check it easily - compile CommandBarControls sample.
Run it. Enter customization mode. Resize CXTPControlComboBox. Close the application. Now run again - YOUR EDITS ARE LOST.
Tomasz
|
|
Tomasz
Senior Member Joined: 05 August 2006 Status: Offline Points: 109 |
Post Options
Thanks(0)
|
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.
|
|
Tomasz
Senior Member Joined: 05 August 2006 Status: Offline Points: 109 |
Post Options
Thanks(0)
|
Working fix:
Inside CXTPZipMemFile declaration:
BOOL OpenCompressedFile(LPCTSTR lpszFileName)
{ if (!CFile::Open(lpszFileName, CFile::modeRead)) return FALSE; // FIX:
UINT nSize = ::GetFileSize( (HANDLE)m_hFile, NULL); // UINT nSize = (UINT)CFile::GetLength(); // THIS IS WRONG
LPBYTE lpBuffer = (LPBYTE)malloc(nSize); CFile::Read(lpBuffer, nSize); CFile::Close();
AttachCompressedBuffer(lpBuffer, nSize, TRUE);
return TRUE;
} |
|
Oleg
Admin Group Joined: 21 May 2003 Location: United States Status: Offline Points: 11234 |
Post Options
Thanks(0)
|
:-(
Thanks, you absolutely right :(
Fixed for 11.2.1 release
|
|
Oleg, Support Team
CODEJOCK SOFTWARE SOLUTIONS |
|
Post Reply | |
Tweet
|
Forum Jump | Forum Permissions You cannot post new topics in this forum You cannot reply to topics in this forum You cannot delete your posts in this forum You cannot edit your posts in this forum You cannot create polls in this forum You cannot vote in polls in this forum |