Thank you for the interesting information. Your improved version of the _FindMessageMapHandler()
method works only with Visual Studio 2005 (8.0) and later Visual Studio versions. The GetThisMessageMap()
API is not present in Visual C++ 6.0 and it’s present in Visual Studio .NET (7.0) and Visual Studio .NET 2003 (7.1) only in the DLL version of MFC (when the _AFX_DLL
preprocessor symbol is defined while compiling MFC-based project). This means your good improvement cannot be applied as is because we support compatibility with Visual Studio versions older than Visual Studio 2005 (8.0). We spend several hours on improving your good version of the _FindMessageMapHandler()
method. Here is the updated version of the .../Prof-UIS/Include/ExtTempl.h file:
http://www.prof-uis.com/download/forums/tmp/ExtTempl_h_for_Nikita_Davydov.zip
What’s new in this header file? The CExtWS::WindowProc()
method handles the WM_PAINT
message a bit differently and searches/invokes message map handlers before doing default painting. Of course, our version of the _FindMessageMapHandler()
method is also there:
const AFX_MSGMAP_ENTRY * _FindMessageMapHandler( UINT nMsg, UINT nCode, UINT nID )
{
ASSERT_VALID( this );
UINT nEntry = 0;
const AFX_MSGMAP_ENTRY * lpEntry = NULL;
const AFX_MSGMAP * pMessageMap = GetMessageMap();
#if ( _MFC_VER >= 0x800 )
const AFX_MSGMAP * pThisMessageMap = GetThisMessageMap();
for( ; pThisMessageMap != pMessageMap && pMessageMap != NULL; pMessageMap = pMessageMap->pfnGetBaseMap() )
{
for( nEntry = 0, lpEntry = NULL; ( lpEntry = ( pMessageMap->lpEntries + nEntry ) ) -> nSig != AfxSig_end; nEntry ++ )
{
if( lpEntry->nMessage == nMsg
&& lpEntry->nCode == nCode
&& lpEntry->nID <= nID && nID <= lpEntry->nLastID
)
return lpEntry;
}
if( pMessageMap->pfnGetBaseMap == NULL )
return NULL;
}
#else // ( _MFC_VER >= 0x800 )
#if ( defined _AFXDLL )
for( ; pMessageMap != NULL; pMessageMap = (*pMessageMap->pfnGetBaseMap)() )
#else
for( ; pMessageMap != NULL; pMessageMap = pMessageMap->pBaseMap )
#endif
{
for( nEntry = 0, lpEntry = NULL; ( lpEntry = ( pMessageMap->lpEntries + nEntry ) ) -> nSig != AfxSig_end; nEntry ++ )
{
if( lpEntry->nMessage == nMsg
&& lpEntry->nCode == nCode
&& lpEntry->nID <= nID && nID <= lpEntry->nLastID
)
return lpEntry;
}
}
#endif // else from ( _MFC_VER >= 0x800 )
return NULL;
}
It’s tested and works with Visual C++ 6.0, Visual Studio 2005 (8.0), Visual Studio 2008 (9.0) and Visual Studio 2010 beta 2 (10.0). It’s buggy with Visual Studio .NET (7.0) and Visual Studio .NET 2003 (7.1) because the message map implementation in these VS versions is different and does not allow to detect the
pThisMessageMap
pointer in all the cases because the
GetThisMessageMap()
API is present in the DLL MFC version only. As result, the
CDialog::OnPaint()
handler method is always invoked. This is not a problem for Visual C++ 6.0 because there is no
CDialog::OnPaint()
method there.
In conclusion, we keep this question open and continue searching for a better solution. We would like to ask you to handle the
WM_PAINT
messages in the
WindowProc()
virtual method in all your
CExtWS
-based windows including
CExtResizableDailog
-derived classes.