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 Tech Support » Wizard Collapse All
Subject Author Date
Eddie Judson Mar 26, 2007 - 9:38 PM

Hi,
I am using VS 8, and have a couple of wizards in my program, when I compile my program in release mode and try to display the wizard it crashes, but only if the wizard contains more than two property pages, if it contains only one then it is fine. I have put together a sample program that you can download from:

http://www.quiltech.com.au/TestResizablePropertySheet.zip

Please note you have to compile it in release mode and run it from outside the IDE to get the crash. Can you please help me find the problem?
    Regards,
        Eddie

Eddie Judson Mar 29, 2007 - 12:17 AM

More info on the problem:
It seems to be coming from this function
CExtResPS::BuildPropPageArray()

the second iteration of this is causing the crash
__EXT_MFC_MEMCPY(
            ppsp,
            ppsp->dwSize,
            &pPage->m_psp,
            pPage->m_psp.dwSize
            );


if I use the old memcpy instead of the new safe version it works fine and doesn’t crash (not an idle solution)

inline void __EXT_MFC_MEMCPY(
    void * dest,
    size_t sizeInBytes,
    const void * src,
    size_t count
    )
{
    /*#if _MFC_VER >= 0x0800
        memcpy_s( dest, sizeInBytes, src, count );
    #else*/
        memcpy( dest, src, count );
        sizeInBytes;
    //#endif
}

Technical Support Mar 29, 2007 - 11:38 AM

This bug is fixed. You can download the latest library version from our ftp server or you can fix it manually by updating the CExtResPS::BuildPropPageArray() method in ExtCmdManager.cpp:

void CExtResPS::BuildPropPageArray()
{
#if _MFC_VER < 0x700
    if( m_psh.ppsp != NULL )
        delete [] (PROPSHEETPAGE *) m_psh.ppsp;
    m_psh.ppsp = NULL;
AFX_OLDPROPSHEETPAGE * ppsp =
        new AFX_OLDPROPSHEETPAGE[ m_pages.GetSize() ];
    ::memset( ppsp, 0, m_pages.GetSize() * sizeof(AFX_OLDPROPSHEETPAGE) );
    m_psh.ppsp = (LPPROPSHEETPAGE) ppsp;
BOOL bWizard = ( m_psh.dwFlags & (PSH_WIZARD | PSH_WIZARD97) );
    for( int i = 0; i < m_pages.GetSize(); i++ )
    {
        CPropertyPage * pPage = GetPage(i);
        __EXT_MFC_MEMCPY(
            &ppsp[i], 
            sizeof(AFX_OLDPROPSHEETPAGE),
            & pPage->m_psp, 
            pPage->m_psp.dwSize 
            );
        CExtResPP * pExtResourcePropertyPage =
            DYNAMIC_DOWNCAST( CExtResPP, pPage );
        if( pExtResourcePropertyPage != NULL )
            pExtResourcePropertyPage->PreProcessPageTemplate(
                (PROPSHEETPAGE&) ppsp[i],
                bWizard
                );
        else
        {
            struct friendly_property_page_t : public CPropertyPage
            {
            public:
                friend class CExtResPS;
            };
            ((friendly_property_page_t *)pPage)->PreProcessPageTemplate(
                (PROPSHEETPAGE&) ppsp[i],
                bWizard
                );
        }
    } // for( int i = 0; i < m_pages.GetSize(); i++ )
    m_psh.nPages = m_pages.GetSize();
#else
    if( m_psh.ppsp != NULL )
    {
        free((void*)m_psh.ppsp);
        m_psh.ppsp = NULL;
    }
    int i;
    int nBytes = 0;
    for( i = 0; i < m_pages.GetSize(); i++ )
    {
        CPropertyPage* pPage = GetPage(i);
        nBytes += pPage->m_psp.dwSize;
    }
    PROPSHEETPAGE * ppsp = (PROPSHEETPAGE *)malloc( nBytes );
    if( ppsp == NULL )
        AfxThrowMemoryException();
    ::memset( ppsp, 0, nBytes );
    m_psh.ppsp = ppsp;
    BOOL bWizard = (m_psh.dwFlags & (PSH_WIZARD | PSH_WIZARD97));
    for( i = 0; i < m_pages.GetSize(); i++ )
    {
        struct friendly_property_page_t : public CPropertyPage
        {
        public:
            friend class CExtResPS;
        };
        friendly_property_page_t * pPage =
            (friendly_property_page_t *) GetPage(i);
        __EXT_MFC_MEMCPY( 
            ppsp, 
            sizeof(PROPSHEETPAGE),
            &pPage->m_psp, 
            pPage->m_psp.dwSize 
            );
        if (!pPage->m_strHeaderTitle.IsEmpty())
        {
            ppsp->pszHeaderTitle = pPage->m_strHeaderTitle;
            ppsp->dwFlags |= PSP_USEHEADERTITLE;
        }
        if (!pPage->m_strHeaderSubTitle.IsEmpty())
        {
            ppsp->pszHeaderSubTitle = pPage->m_strHeaderSubTitle;
            ppsp->dwFlags |= PSP_USEHEADERSUBTITLE;
        }
        CExtResPP * pExtResourcePropertyPage =
            DYNAMIC_DOWNCAST( CExtResPP, pPage );
        if( pExtResourcePropertyPage != NULL )
            pExtResourcePropertyPage->PreProcessPageTemplate(
                *ppsp,
                bWizard
                );
        else
            pPage->PreProcessPageTemplate(
                *ppsp,
                bWizard
                );
        (BYTE*&)ppsp += ppsp->dwSize;
    } // for( i = 0; i < m_pages.GetSize(); i++ )
    m_psh.nPages = (int)m_pages.GetSize();
#endif
}


Eddie Judson Mar 28, 2007 - 5:04 PM

Here is the call stack where it crashes, yes I have run it on other machines and it does experience the same problem. Here is the result of the dump:

TestResizablePropertySheet.exe!_crt_debugger_hook(int _Reserved=) Line 65    C
TestResizablePropertySheet.exe!_invalid_parameter(const wchar_t * pszExpression=0x00000000, const wchar_t * pszFunction=0x00000000, const wchar_t * pszFile=0x00000000, unsigned int nLine=0, unsigned int pReserved=0) Line 86 + 0x7 bytes    C++
TestResizablePropertySheet.exe!memcpy_s(void * dst=0x014cb8e8, unsigned int sizeInBytes=0, const void * src=0x014cb7b0, unsigned int count=48) Line 55 + 0x19 bytes    C
TestResizablePropertySheet.exe!CExtResPS::BuildPropPageArray() + 0xd0 bytes    C++
TestResizablePropertySheet.exe!CPropertySheet::DoModal() Line 931    C++
TestResizablePropertySheet.exe!CTestResizablePropertySheetDlg::OnBnClickedBtnDisplayWiz3Pages() Line 168    C++
TestResizablePropertySheet.exe!_AfxDispatchCmdMsg(CCmdTarget * pTarget=0x0012fe70, unsigned int nID=1001, int nCode=0, void (void)* pfn=0x00404f70, void * pExtra=0x00000000, unsigned int nSig=56, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Line 82    C++
TestResizablePropertySheet.exe!CCmdTarget::OnCmdMsg(unsigned int nID=1001, int nCode=0, void * pExtra=0x00000000, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Line 381 + 0x18 bytes    C++

Technical Support Mar 28, 2007 - 10:31 AM

We have compiled and run your test project successfully without any crashes. Did you try to check the problem on some other computer? In any case, you should compile the release configuration with the debugging information turned on in the project’s compiler and linker settings, then run the application outside the wizard and attach the Visual Studio debug session to it when the crash occurs. If you send us the content of the Call Stack window, that would help us find out what’s wrong.