Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS General Discussion » Exceptions Collapse All
Subject Author Date
Jonas Gauffin Dec 1, 2005 - 7:37 AM

In the method "bool CExtCmdProfile::SerializeState" you handle exceptions in the following way:

    catch( CException * pXept )
    {
        pXept->Delete();
        ASSERT( FALSE );
    } // catch( CException * pXept )
    catch( ... )
    {
        ASSERT( FALSE );
    } // catch( ... )

Please do not do that. I have no clue what so ever why the serialization fails since you eat the excepton and do an ASSERT(FALSE) only.

Also, the example StateInFile have a CException handling too, but that handling will never be used since you catch the excepton in the framework.

Also, catch (...) or catch (CException) is not recommended at all since it eats ALL exceptions / mfc exceptions. Exceptions like CMemoryException should not be handled by you because it, most problably, indicates a memory leak somewhere in the application.

Conclusion:
Let user handle the exceptions instead of the framework, what you can do is to document which exceptions the code can throw (in this case CArchiveException only)
Different exceptions should be handled differently.

Technical Support Dec 1, 2005 - 8:32 AM

You have brought up a very interesting theme for discussion. On the one hand, there is no problem with catching all exceptions in some Prof-UIS methods and returning false to indicate an error. Yes, we catch all the exceptions when some Prof-UIS internal part serializes its state. We think there is no reason to let the user catch our internal exceptions and guess what’s wrong with the registry or file. The size of the serialized data is always much less 100 kb. So, this approach is more painless for users. On the other hand, we could allow the user to catch any exception and do what they need. In this case, we need to add the bool bThrowExceptions parameter to several ...Serialize() methods. For instance, the HeapAlloc() Win32 API allows you to specify whether it is enabled to throw SEH exception in case if heap allocation failed.

Jonas Gauffin Dec 1, 2005 - 10:50 AM

Then you need to change the example too, no need to handle exceptions in it.

I need to find out why CExtCmdProfile::SerializeState fails when loading the state from a file.
The file serialization doesnt work for me, how do I find the error?

Technical Support Dec 1, 2005 - 11:54 AM

There are two basic loading errors may occur during serialization:

1) File and/or format errors. The specified file or registry location does not exist or its content has invalid format.

2) File and its format are valid but its content does not correspond to the data structure whose state is being loaded. Your code loads command state which contains state records of not existing commands. Your code loads bar state which contains state of bars which are not present (not created) in the frame window.

Jonas Gauffin Dec 1, 2005 - 1:15 PM

What is the correct way of handling these errors?
And how do I find out which error it is?

Simply ignore them doesnt work.

Technical Support Dec 2, 2005 - 4:20 AM

As we said in the previous message, it is not possible to know whether the file exists or it has an invalid format. Besides, some customers even asked us to remove any assertions from catch sections. So, we just continued this discussion to ask you whether you really need to catch these exceptions. If you need, we will modify serialization methods so that the exceptions cab be thrown out from them optionally.

Jonas Gauffin Dec 2, 2005 - 6:15 AM

It would be nice to be able to handle exceptions (as they are an important part of C++). But I can understand that you do not want to change your current structure.

I solved it by putting a breakpoint in your class and casted CException to CArchiveException. The reaons why the load serialization fails is:
CArchiveException::endOfFile Reached end of file while reading an object.

Technical Support Dec 3, 2005 - 7:33 AM

We have modified the following methods: CExtControlBar::ProfileBarStateSerialize(), CExtControlBar::ProfileBarStateLoad(), CExtControlBar::ProfileBarStateSave(), CExtDynamicBarSite::StateSerialize(), CExtDynamicBarSite::StateLoad(), CExtDynamicBarSite::StateSave(), CExtCmdManager::FileObjFromRegistry(), CExtCmdManager::FileObjToRegistry(), CExtCmdProfile::SerializeState() (2 methods), CExtCmdManager::SerializeState() (2 methods), CExtCustomizeSite::CustomizeStateLoad(), CExtCustomizeSite::CustomizeStateSave(), and CExtCustomizeSite::CustomizeStateSerialize(). All of them now have the bEnableThrowExceptions flag as the last method parameter and return a flag which indicates the operation success. By default, the bEnableThrowExceptions flag is set to false and your code should analyze the returned flag. If you set this parameter to true then there are two execution results can occur for each of improved methods: returned true on success and thrown out exception on any failure. Please drop us a line by e-mail so we can provide you with the source code update.

Jonas Gauffin Dec 5, 2005 - 12:46 AM

omg, thank you =)

Wu Yunpeng Dec 1, 2005 - 7:39 PM

i had the same problem as you.


you must create command id(eg.ID_VIEW_BAR1, and put it into menu resource) for each CExtControlBar object.


and the command id is just the id used in Create method of CExtControlBar,which is as follows:


m_wndResizableBar1.Create(NULL,this,ID_VIEW_BAR1); 


 

Technical Support Dec 2, 2005 - 4:30 AM

Wu, first of all, your message does not describe any problem and, it has nothing to do with the try..catch usage we are discussing with Jonas in this thread. We guess what wanted to ask us is whether you need to to add menu commands for each created bar ... but is it a real problem? These command ids are required to show/hide your control bars when you click corresponding menu items and/or toolbar buttons.

Jonas Gauffin Dec 2, 2005 - 3:49 AM

I have only one ControlBar and it got an id.

Technical Support Dec 2, 2005 - 7:59 AM

Surely, if you have only one resizable control bar, then you can use an identifier predefined in MFC like AFX_IDW_DIALOG_BAR.

Jonas Gauffin Dec 5, 2005 - 12:46 AM

Nah. Getting two-three more bars in the next version of the client.

Technical Support Dec 5, 2005 - 5:38 AM

So, you will have to assign unique command identifiers for all your bars and insert appropriate message map entries. Here are the message map lines for the bar with the ID_MY_BAR identifier (can be either a toolbar, menu bar, resizable bar, status bar, or MFC’s control bar):

ON_COMMAND_EX( ID_MY_BAR, OnBarCheck )
ON_UPDATE_COMMAND_UI( ID_MY_BAR, OnUpdateControlBarMenu )
The OnBarCheck() and OnUpdateControlBarMenu() methods are defined in MFC’s CFrameWnd class and they are very handy for using in the message map. But if you use auto-hide enabled resizable bars, then you need redefine these two methods in your main frame class as it is done in the ProfStudio sample:
void CMainFrame::OnUpdateControlBarMenu(CCmdUI* pCmdUI)
{
    // CFrameWnd::OnUpdateControlBarMenu( pCmdUI );
    CExtControlBar::DoFrameBarCheckUpdate(
        this,
        pCmdUI,
        false
        );
}
 
BOOL CMainFrame::OnBarCheck(UINT nID)
{
    // return CFrameWnd::OnBarCheck( nID );
    return
        CExtControlBar::DoFrameBarCheckCmd(
            this,
            nID,
            false
            );
}