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.
Subject |
Author |
Date |
|
Arjan
|
Nov 13, 2009 - 6:34 AM
|
Keyboard-input in a CExtGrid crashes application.
To be more precise, we’re using a CExtTreeGridWnd. Cells are of the class CExtGridCellString. Styled applied to the cell is __EGCS_NO_INPLACE_CONTROL.
When a cell is selected and there’s keyboard input, nothing should happen. However, the effect is that the application crashes.
We discovered the problem to be caused in CExtGridWnd::OnGbwBeginEdit (file "ExtGridWnd.cpp"). Eventualy theres the following code in that routine: if( strStartEditText != NULL ) { bool bSetText = true; TCHAR strClassName[512]; ::GetClassName( m_hWndInplaceControl, strClassName, 512 ); if( _tcslen( strClassName ) > 0 ) { ....etc.
What happens is that there is no InplaceControl, which implies m_hWndInplaceControl==NULL. This also implies that GetClassName does nothing. This also implies that strClassName is undefined/uninitialized. This also implies that ( _tcslen( strClassName ) > 0 ) is undefined.
A simple solution would be, the make sure strClassName is always initialized with an empty string. We’ve changed the code to the following: TCHAR strClassName[512]; strClassName[0] = 0; ::GetClassName( m_hWndInplaceControl, strClassName, 512 );
Eventhough this seems to work, the real question ofcourse is why we’re even in this part of the routine since m_hWndInplaceControl==NULL. Perhaps this is something to take in consideration in a new release of ProfUIS.
Kind regards, Arjan Lukkesen Ellips B.V.
|
|
Technical Support
|
Nov 13, 2009 - 1:42 PM
|
Thank you very much for reporting us this issue. Here is the corrected part of the CExtGridWnd::OnGbwBeginEdit() method:
if( strStartEditText != NULL
&& _tcslen( strStartEditText ) > 0
&& m_hWndInplaceControl != NULL
&& ::IsWindow( m_hWndInplaceControl )
)
{
bool bSetText = true;
TCHAR strClassName[512+1];
::memset( &strClassName, 0, sizeof(strClassName) );
::GetClassName( m_hWndInplaceControl, strClassName, 512 );
if( _tcslen( strClassName ) > 0 )
{
|
|
Rolf Boerkoel
|
Nov 13, 2009 - 2:05 AM
|
Dear support, I have a property grid on a CExtResizableDialog dialog. This dialog is a child of another dialog. Navigating through the several property items with the tab key does not work as it normally does, unless I manually set m_bAllowLongFocusJumpFix = false
in the child dialog. 1) Is it correct and/or safe to set this m_bAllowLongFocusJumpFix member to false to allow tabbing through the items? 2) I see that this m_bAllowLongFocusJumpFix is only explicitly initialized in the CExtResizableDialog’s default constructor, not in the two other constructors, could this be a small bug? Regards, Marco
|
|
Technical Support
|
Nov 18, 2009 - 6:50 AM
|
You can set the g_bAllowLongFocusJumpFix flag to false and use this temporarily solution. But it should work OK when it’s set to true . We need to repeat this problem in any of Prof-UIS sample applications or in some test project. Could you please provide us with a test project or with exact window layout description which reproduces the tab navigation problem?
|
|
Rolf Boerkoel
|
Nov 18, 2009 - 9:26 AM
|
I sent you a test project by email.
|
|
Rolf Boerkoel
|
Nov 16, 2009 - 2:33 AM
|
Then it is a bug.My child dialog is created with the second CExtResizableDialog constructor. As m_bAllowLongFocusJumpFix is initialized with a random value when using the 2nd or 3rd constructor, tabbing sometimes works and sometimes it doesn’t: CExtResizableDialog::CExtResizableDialog()
: m_bEnabledControlBarUpdate( false )
, m_bInConrolBarUpdate( false )
, m_bAllowLongFocusJumpFix( g_bAllowLongFocusJumpFix )
, m_hWndFocus( NULL )
, m_bHelperSizingMoving( false )
{
m_bShowResizingGripper = true;
}
CExtResizableDialog::CExtResizableDialog(
UINT nIDTemplate,
CWnd * pParentWnd
)
: CExtWA < CExtWS < __BASEOF_CExtResizableDialog__ > > ( nIDTemplate, pParentWnd )
, m_bEnabledControlBarUpdate( false )
, m_bInConrolBarUpdate( false )
, m_hWndFocus( NULL )
, m_bHelperSizingMoving( false )
{
m_bShowResizingGripper = true;
}
CExtResizableDialog::CExtResizableDialog(
__EXT_MFC_SAFE_LPCTSTR lpszTemplateName,
CWnd * pParentWnd
)
: CExtWA < CExtWS < __BASEOF_CExtResizableDialog__ > > ( lpszTemplateName, pParentWnd )
, m_bEnabledControlBarUpdate( false )
, m_bInConrolBarUpdate( false )
, m_hWndFocus( NULL )
, m_bHelperSizingMoving( false )
{
m_bShowResizingGripper = true;
}
|
|
Technical Support
|
Nov 18, 2009 - 2:07 PM
|
We received your e-mail and replied it.
|
|
Rolf Boerkoel
|
Nov 19, 2009 - 3:05 AM
|
Seems to work fine now, thank you. I have one (slightly off topic) remaining question/problem:
Our property grid is set up in two stages. First it is initialized with default values. Later on the actual values are put into the grid (well, actually in the property store, of course). To make these new values become visible, we call the PropertyStoreSynchronize() method. The new values indeed become visible. So we’re doing something like this (simplified): void InitPropertyGrid()
{
CreateCategories();
CreatePropertyValues();
propertyGrid.PropertyStoreSet(&propertyStore);
}
void UpdatePropertyGrid()
{
UpdatePropertyValues();
propertyGrid.PropertyStoreSynchronize();
}
However by calling PropertyStoreSynchronize() the grid seems to loose its focus. In some situations it even means the dialog gets locked up. Even pressing the tab key doesn’t help. Only by using the mouse (or by pressing up or down arrow key) one can get it to work again. After some investigation I discovered that calling PropertyStoreSet instead of PropertyStoreSynchronize makes this problem disappear. I’m completely happy with calling PropertyStoreSet method, but what do you think? I thought PropertyStoreSynchronize was the recommended way of updating the grid? Is the PropertyStoreSynchronize method still useful in some situations?
|
|
Technical Support
|
Nov 19, 2009 - 1:51 PM
|
We agree, the focus should not be lost in the property grid after synchronization. Please update the source code for the following method:
void CExtPropertyGridCtrl::PropertyStoreSynchronize()
{
ASSERT_VALID( this );
_EnsureInitialized();
CExtPropertyGridWnd * pActivePGW = NULL;
CExtPropertyStore * pCurrentPS = PropertyStoreGet();
CExtPropertyItem * pRestoreFocusPI = NULL;
if( pCurrentPS != NULL )
{
ASSERT_VALID( pCurrentPS );
pActivePGW = GetActiveGrid();
if( pActivePGW->GetSafeHwnd() != NULL )
{
ASSERT_VALID( pActivePGW );
HTREEITEM htiFocus = pActivePGW->ItemFocusGet();
if( htiFocus != NULL )
pRestoreFocusPI = pActivePGW->PropertyItemFromTreeItem( htiFocus );
}
}
CTypedPtrArray < CPtrArray, CExtPropertyGridWnd * > arrGrids;
OnPgcQueryGrids( arrGrids );
INT nGridIdx = 0;
for( ; nGridIdx < arrGrids.GetSize(); nGridIdx ++ )
{
CExtPropertyGridWnd * pGrid = arrGrids[ nGridIdx ];
ASSERT_VALID( pGrid );
pGrid->PropertyStoreSynchronizeAll();
} // for( ; nGridIdx < arrGrids.GetSize(); nGridIdx ++ )
if( pRestoreFocusPI != NULL )
{
ASSERT_VALID( pActivePGW );
ASSERT( pActivePGW->GetSafeHwnd() != NULL );
HTREEITEM htiSetFocus = pActivePGW->PropertyItemToTreeItem( pRestoreFocusPI );
if( htiSetFocus != NULL )
pActivePGW->ItemFocusSet( htiSetFocus );
}
}
|
|
Rolf Boerkoel
|
Nov 20, 2009 - 2:16 AM
|
This solves the focus problem, thanks. But I keep on nagging (sorry)...
The tabbing works ok when the property grid is on a dialog which is a child of another dialog. But the tabbing doesn’t seem to work anymore in the more common case of having a property grid as a direct child of a dialog. Again when setting the m_bAllowLongFocusJumpFix to false it works ok.
I sent you another test project (sample11) which illustrates this case.
|
|
Technical Support
|
Nov 16, 2009 - 1:32 PM
|
Thank you very much for reporting this issue. The m_bAllowLongFocusJumpFix must be initialized in all the CExtResizableDialog class constructors:
CExtResizableDialog::CExtResizableDialog()
: m_bEnabledControlBarUpdate( false )
, m_bInConrolBarUpdate( false )
, m_hWndFocus( NULL )
, m_bHelperSizingMoving( false )
, m_bAllowLongFocusJumpFix( g_bAllowLongFocusJumpFix )
{
m_bShowResizingGripper = true;
}
CExtResizableDialog::CExtResizableDialog(
UINT nIDTemplate,
CWnd * pParentWnd
)
: CExtWA < CExtWS < __BASEOF_CExtResizableDialog__ > > ( nIDTemplate, pParentWnd )
, m_bEnabledControlBarUpdate( false )
, m_bInConrolBarUpdate( false )
, m_hWndFocus( NULL )
, m_bHelperSizingMoving( false )
, m_bAllowLongFocusJumpFix( g_bAllowLongFocusJumpFix )
{
m_bShowResizingGripper = true;
}
CExtResizableDialog::CExtResizableDialog(
__EXT_MFC_SAFE_LPCTSTR lpszTemplateName,
CWnd * pParentWnd
)
: CExtWA < CExtWS < __BASEOF_CExtResizableDialog__ > > ( lpszTemplateName, pParentWnd )
, m_bEnabledControlBarUpdate( false )
, m_bInConrolBarUpdate( false )
, m_hWndFocus( NULL )
, m_bHelperSizingMoving( false )
, m_bAllowLongFocusJumpFix( g_bAllowLongFocusJumpFix )
{
m_bShowResizingGripper = true;
}
|
|
Technical Support
|
Nov 20, 2009 - 2:40 PM
|
Thank you for all your test projects. Please update the source code for the following two methods:
LRESULT CExtPropertyGridWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if( message == WM_PRINT
|| message == WM_PRINTCLIENT
)
{
CDC * pDC = CDC::FromHandle( (HDC) wParam );
CRect rcWnd, rcClient;
GetWindowRect( &rcWnd );
GetClientRect( &rcClient );
ClientToScreen( rcClient );
rcClient.OffsetRect( -rcWnd.TopLeft() );
rcWnd.OffsetRect( -rcWnd.TopLeft() );
if( (lParam&PRF_NONCLIENT) != 0 )
{
CExtMemoryDC dc(
pDC,
&rcWnd
);
dc.ExcludeClipRect(rcClient);
PmBridge_GetPM()->PaintResizableBarChildNcAreaRect(
dc,
rcWnd,
this
);
dc.SelectClipRgn( NULL );
}
if( (lParam&(PRF_CLIENT|PRF_ERASEBKGND)) != 0 )
{
CExtMemoryDC dc(
pDC,
&rcClient
);
CPoint ptVpOffset( 0, 0 );
if( (lParam&PRF_NONCLIENT) != 0 )
{
ptVpOffset.x = rcWnd.left - rcClient.left;
ptVpOffset.y = rcWnd.top - rcClient.top;
}
if( ptVpOffset.x != 0
|| ptVpOffset.y != 0
)
dc.OffsetViewportOrg(
-ptVpOffset.x,
-ptVpOffset.y
);
OnSwPaint( dc );
if( ptVpOffset.x != 0
|| ptVpOffset.y != 0
)
dc.OffsetViewportOrg(
ptVpOffset.x,
ptVpOffset.y
);
} // if( (lParam&(PRF_CLIENT|PRF_ERASEBKGND)) != 0 )
if( (lParam&PRF_CHILDREN) != 0 )
CExtPaintManager::stat_PrintChildren(
m_hWnd,
message,
pDC->GetSafeHdc(),
lParam,
false
);
return (!0);
}
LRESULT lResult = CWnd::WindowProc( message, wParam, lParam );
if( message == WM_GETDLGCODE )
lResult |= DLGC_WANTTAB;
return lResult;
}
BOOL CExtResizableDialog::PreTranslateMessage(MSG* pMsg)
{
if( WM_KEYFIRST <= pMsg->message
&& pMsg->message <= WM_KEYLAST
&& GetSafeHwnd() != NULL
&& ( pMsg->hwnd == m_hWnd || ::IsChild( m_hWnd, pMsg->hwnd ) )
&& (GetStyle()&(WS_VISIBLE|WS_DISABLED)) == WS_VISIBLE
)
{ // pre translating keyboard input (if enabled/visible dialog)
if( pMsg->wParam == VK_TAB )
{
if( m_bAllowLongFocusJumpFix )
{
if( pMsg->message == WM_KEYDOWN )
{
HWND hWnd = ::GetFocus();
if( hWnd != NULL )
{
bool bWantsTab = ( ( ::SendMessage( hWnd, WM_GETDLGCODE, VK_TAB, 0 ) & DLGC_WANTTAB ) != 0 ) ? true : false;
if( bWantsTab )
{
CWnd * pWnd = CWnd::FromHandlePermanent( hWnd );
if( pWnd != NULL
&& ( pWnd->IsKindOf( RUNTIME_CLASS(CDialog) )
#if (!defined __EXT_MFC_NO_TAB_PAGECONTAINER_CTRL)
|| pWnd->IsKindOf( RUNTIME_CLASS(CExtTabPageContainerWnd) )
#endif // (!defined __EXT_MFC_NO_TAB_PAGECONTAINER_CTRL)
)
)
bWantsTab = false;
} // if( bWantsTab )
if( ! bWantsTab )
{
HWND hWndMain = m_hWnd;
if( ( __EXT_MFC_GetWindowLong( hWndMain, GWL_STYLE ) & WS_CHILD ) != 0 )
hWndMain = ::GetParent( m_hWnd );
for( ; ( __EXT_MFC_GetWindowLong( hWndMain, GWL_STYLE ) & WS_CHILD ) != 0 ; )
hWndMain = ::GetParent( hWndMain );
if( hWndMain != NULL )
{
BOOL bPrevious = CExtPopupMenuWnd::IsKeyPressed( VK_SHIFT );
hWnd = stat_GetNextItemZ( hWndMain, m_hWnd, hWnd, bPrevious );
//hWnd = ::GetNextDlgTabItem( m_hWnd, hWnd, CExtPopupMenuWnd::IsKeyPressed( VK_SHIFT ) );
if( hWnd != NULL )
{
//CWnd * pWnd = CWnd::FromHandlePermanent( hWnd );
g_bProcessingLongFocusJump = true;
g_bProcessingLongFocusJumpToPrevDir = bPrevious ? true : false;
::SetFocus( hWnd );
if( ::SendMessage( hWnd, WM_GETDLGCODE, WPARAM(VK_TAB), LPARAM(pMsg) ) )
::SendMessage( hWnd, EM_SETSEL, WPARAM(0L), LPARAM(-1L) );
g_bProcessingLongFocusJump = false;
//pWnd;
}
}
} // if( ! bWantsTab )
else
return FALSE;
} // if( hWnd != NULL )
} // if( pMsg->message == WM_KEYDOWN )
return TRUE;
} // if( m_bAllowLongFocusJumpFix )
} // if( pMsg->wParam == VK_TAB )
else
{
if( (GetStyle()&(WS_VISIBLE|WS_CHILD)) == (WS_VISIBLE|WS_CHILD) )
{ // if child/visible dialog
HWND hWndParent = ::GetParent( m_hWnd );
CWnd * pWndParentPermanent = CWnd::FromHandlePermanent( hWndParent );
if( pWndParentPermanent != NULL
&& ( pWndParentPermanent->IsKindOf( RUNTIME_CLASS(CExtControlBar) )
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
|| pWndParentPermanent->IsKindOf( RUNTIME_CLASS(CExtDynAutoHideSlider) )
#endif // (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
)
&& pWndParentPermanent->PreTranslateMessage(pMsg)
)
return TRUE;
} // if child/visible dialog
} // else from if( pMsg->wParam == VK_TAB )
HWND hWndFocus = ::GetFocus();
if( hWndFocus != NULL
&& ::GetParent( hWndFocus ) == m_hWnd
//&& ( ::SendMessage( hWndFocus, WM_GETDLGCODE, 0L, 0L ) & (DLGC_WANTCHARS|DLGC_WANTALLKEYS) == 0 )
)
{
bool bProcessKey = false;
BOOL bAlt = HIWORD(pMsg->lParam) & KF_ALTDOWN;
LRESULT lRDC = ::SendMessage( hWndFocus, WM_GETDLGCODE, pMsg->wParam, 0L );
if( ( lRDC & DLGC_WANTALLKEYS ) == 0
&& ( ( lRDC & DLGC_WANTCHARS ) == 0
|| bAlt
)
)
{
bProcessKey = true;
}
if( bProcessKey )
{
//BOOL bKeyUp = ( pMsg->message == WM_KEYUP || pMsg->message == WM_SYSKEYUP) ? TRUE : FALSE;
BOOL bCtrl = GetKeyState(VK_CONTROL) & 0x80000000;
BOOL bShift = GetKeyState(VK_SHIFT) & 0x80000000;
if( ! ( bCtrl || bShift ) )
{
TCHAR vkTCHAR = (TCHAR)pMsg->wParam;
BYTE lpKeyState[256];
::GetKeyboardState( lpKeyState );
UINT wScanCode = ::MapVirtualKey( vkTCHAR, 0 );
HKL hKeyboardLayout =
::GetKeyboardLayout(
( ::AfxGetThread() ) -> m_nThreadID
);
#if (defined _UNICODE)
TCHAR szChar[2] = { _T(’\0’), _T(’\0’) };
::ToUnicodeEx(
vkTCHAR,
wScanCode,
lpKeyState,
szChar, 1,
1,
hKeyboardLayout
);
#else
WORD nMapped = 0;
::ToAsciiEx(
vkTCHAR,
wScanCode,
lpKeyState,
&nMapped,
1,
hKeyboardLayout
);
TCHAR szChar[2] = { (TCHAR)nMapped, _T(’\0’) };
#endif
::CharUpper( szChar );
if( szChar[0] != 0 )
{
HWND hWnd = ::GetWindow( m_hWnd, GW_CHILD );
for( ; hWnd != NULL; hWnd = ::GetWindow( hWnd, GW_HWNDNEXT ) )
{
CWnd * pWnd = CWnd::FromHandlePermanent( hWnd );
if( pWnd == NULL )
continue;
if( (pWnd->GetStyle()&(WS_VISIBLE|WS_DISABLED)) != WS_VISIBLE )
continue;
CExtButton * pExtButton = DYNAMIC_DOWNCAST( CExtButton, pWnd );
if( pExtButton == NULL )
continue;
if( pExtButton->m_bQuickActivationEnabled
&& pExtButton->_QuickActivationCheck( DWORD(vkTCHAR) )
)
{
if( pMsg->message == WM_KEYDOWN
|| pMsg->message == WM_SYSKEYDOWN
)
{
if( hWndFocus != pExtButton->m_hWnd )
pExtButton->SetFocus();
}
if( pMsg->message == WM_KEYUP
|| pMsg->message == WM_SYSKEYUP
)
{
if( pExtButton->PreTranslateMessage( pMsg ) )
return TRUE;
}
//break;
return TRUE;
}
}
}
} // if( ! ( bCtrl || bShift ) )
} // if( bProcessKey )
} // if( hWndFocus != NULL && ::GetParent( hWndFocus ) == m_hWnd ...
} // pre translating keyboard input (if enabled/visible dialog)
if( ( GetStyle() & WS_VISIBLE ) != 0
&& CExtControlBar::DoCustomModePreTranslateMessage( this, pMsg )
)
return TRUE;
if( pMsg->message == WM_LBUTTONDOWN )
return FALSE;
return CExtWA < CExtWS < __BASEOF_CExtResizableDialog__ > >::PreTranslateMessage(pMsg);
}
|
|
Rolf Boerkoel
|
Nov 17, 2009 - 2:32 AM
|
You are now initializing them with the value of g_bAllowLongFocusJumpFix, which is true by default. Therefore this will not solve the tabbing problem as it requires the m_bAllowLongFocusJumpFix to be false instead of true. So what is the recommended way to get this to work? Should I set the global g_bAllowLongFocusJumpFix to false myself, or should I set m_bAllowLongFocusJumpFix in every child dialog? Something else?
|
|
Technical Support
|
Nov 13, 2009 - 1:54 PM
|
Your child dialog that is inside other dialog should have the WS_EX_CONTROLPARENT extended window style. Nothing else is needed. Additionally, the property grid control in Prof-UIS 2.87 supports the tab key navigation through it.
|
|
tera tera
|
Nov 12, 2009 - 7:47 PM
|
Hello. I want to transform a CDialog type.
For example, it is a CExtDynamicControlBar type.
Is it impossible? In addition, I want to perform the reverse conversion.
Is it impossible?
|
|
Technical Support
|
Nov 13, 2009 - 1:55 PM
|
You do not need to convert a dialog into a control bar. Just create a dialog as a child of a control bar.
|
|
Dominik Braendlin
|
Nov 10, 2009 - 12:05 AM
|
Dear Tech Support, While browsing the code I found that there is some richedit support in the CExtEditBase class. Unfortunately it seems not to be documented. What is it intended for and how could I use it? Thanks Adrian
|
|
Technical Support
|
Nov 10, 2009 - 2:27 PM
|
The CExtEditBase class can subclass both a simple editor and a rich editor window starting from Prof-UIS 2.85. The CExtFormulaGridWnd formula grid control appeared in 2.87. It uses a rich editor based formula edit control activated as an in-place cell editor of formula cells. We used a rich editor for colorizing formulas. The colorized version of the CExtEditMasked masked edit control and new and colorized system number and system currency editors will appear in Prof-UIS 2.87. All these three edit controls are based on the CExtEditBase class and can work in both simple and rich edit mode. The same masked text, system number and system currency grid cells with optional rich in-place editors are also present in Prof-UIS 2.87. All the UI controls above can use rich editors but all of them use it internally. I.e. you never need to perform rich editor formatting. For instance, rich masked editor allows to specify colors for each validation rule, system number and currency editors allow to specify colors for each number part (whole numbers, fraction numbers, sign, fraction and group separator characters). That’s why we keep the rich editor related methods of the CExtEditBase class as internal. Besides they do approximately the same things as methods of the CRichEditCtrl / CRichEditView MFC classes - in the most cases they just send the standard EM_*** messages specific for rich edit control.
|
|
tera tera
|
Nov 9, 2009 - 7:42 PM
|
Hello. I assign a focus to CButton.
When I push EnterKey, DIALOG is closed.
I change the declaration to CExtRadioButton.
Even if I push EnterKey, DIALOG is not closed.
The boss says that it is such specifications why ??
|
|
tera tera
|
Nov 9, 2009 - 7:07 PM
|
|
|
Technical Support
|
Nov 14, 2009 - 2:15 PM
|
This is fixed in the released Prof-UIS 2.87.
|
|
Offer Har
|
Nov 9, 2009 - 7:48 AM
|
Hi, I have this code in OnInitDialog :
m_grid1.Create(&m_ctrlTab);
m_grid2Create(&m_ctrlTab); And in a much later time I decide if I want to show these tabs:
if (bShowGrid1) m_ctrlTab.PageInsert(m_grid1, "grid 1");
In 2.84 it worked fine, however in 2.87 unless I add this line (after you fixed this function...):
m_ctrlTab.GetSafeTabWindow(); The pages I decide not to show will partially appear if I click in the tab control in the place where there is no tab. This derives, again, from the actual control not being created while the pages are created. Please fix. Thanks, Ron.
|
|
Technical Support
|
Nov 16, 2009 - 1:20 PM
|
Here is the source code of the CExtTabPageContainerWnd::GetSafeTabWindow() method in Prof-UIS 2.87 (just released):
CExtTabWnd * CExtTabPageContainerWnd::GetSafeTabWindow()
{
ASSERT_VALID( this );
VERIFY( _CreateHelper() );
if( m_pWndTab == NULL )
return NULL;
ASSERT_VALID( m_pWndTab );
if( m_pWndTab->GetSafeHwnd() == NULL )
return NULL;
return m_pWndTab;
}
As you can see, it invokes the VERIFY( _CreateHelper() ); code before any other actions. The CExtTabPageContainerWnd::_CreateHelper() method instantiates and create the tab window inside the tab page container: bool CExtTabPageContainerWnd::_CreateHelper()
{
ASSERT_VALID( this );
if( GetSafeHwnd() == NULL )
return false;
if( m_pWndTab == NULL )
m_pWndTab = OnTabWndGetTabImpl();
ASSERT_VALID( m_pWndTab );
if( m_pWndTab != NULL
&& m_pWndTab->m_hWnd == NULL
)
{
if( ! m_pWndTab->Create(
this,
CRect( 0, 0, 0, 0 ),
0x100,
WS_CHILD|WS_VISIBLE, //|WS_TABSTOP,
__ETWS_ORIENT_BOTTOM,
NULL
)
)
return false;
_RepositionBarsImpl();
HookSpyRegister( __EHSEF_KEYBOARD );
}
return true;
}
Please note, all the other methods of the CExtTabPageContainerWnd class are invoking the CExtTabPageContainerWnd::GetSafeTabWindow() method at the beginning. Here is the example: bool CExtTabPageContainerWnd::EnabledBtnHelpGet() const
{
ASSERT_VALID( this );
if( GetSafeTabWindow() == NULL )
return false;
return (m_pWndTab->GetTabWndStyle() & __ETWS_ENABLED_BTN_HELP) ? true : false;
}
This means, the tab page container control in the released Prof-UIS 2.87 works like it did in previous Prof-UIS versions. If you have different source code of the CExtTabPageContainerWnd::GetSafeTabWindow() and CExtTabPageContainerWnd::_CreateHelper() methods, then please update to just released version 2.87.
|
|
Technical Support
|
Nov 9, 2009 - 11:17 AM
|
We cannot confirm this. The CExtTabPageContainerWnd::PageInsert() method invokes the CExtTabPageContainerWnd::_CreateHelper() before registering the page window and the CExtTabPageContainerWnd::_RepositionBarsImpl() finally. The CExtTabPageContainerWnd::_CreateHelper() method creates tab control. The CExtTabPageContainerWnd::_RepositionBarsImpl() method updates internal layout of the tab page container window. Did you override any virtual methods of the CExtTabPageContainerWnd class for changing its default behavior?
|
|
Offer Har
|
Nov 14, 2009 - 2:06 PM
|
Hi, I am telling you that this is what happens to our existing code.... code that worked perfectly fine in 2.84 does not work well in 2.87 unless I add the line that calls GetSafeTabWindow before I do any tab container related work... As you well know, and explained me in the past problem I had with this issue in 2.87, You do not create the tab control window until an explicit call to create it, which is not the same as it was in 2.84, and the problem is right in front of my eyes... and the solution as well! Pleas explain why you are doing this change of not creating the tab control? it seems to break a lot of existing code. Please re-consider this change before the final release of 2.87. By the way when are you going to release 2.87? Thanks, Ron.
|
|
tera tera
|
Nov 6, 2009 - 5:29 PM
|
|
|
Technical Support
|
Nov 8, 2009 - 11:48 AM
|
|
|
tera tera
|
Nov 9, 2009 - 1:32 AM
|
Thank you for an answer.
I program it.
|
|
Rolf Boerkoel
|
Nov 6, 2009 - 4:38 AM
|
Dear support,
I have a CExtButton with a menu attached to it. The menu is not displayed properly in Office2003 themes, it looks like if the menu is clipped or painted over by the background. It gets even more noticable if the menu is popped up near the top/bottom edges of the screen.
I have sent you a small application by email showing the problem.
Kind regards,
Marco
|
|
Technical Support
|
Nov 6, 2009 - 2:07 PM
|
We received your e-mail and replied with the download information for the source code update.
|
|
Rolf Boerkoel
|
Nov 10, 2009 - 2:37 AM
|
Problem solved, thank you.
|
|
Bertil Morefält
|
Nov 5, 2009 - 5:18 AM
|
Hi! I have an MDI application with 28 dll:s (MFC Extenstion DLL:s) and I am trying to bild a new MFC Extenstin DLL where I want to use yours ProfUIS 2.85. My new DLL have CAnvFrame (CMDIChildWnd), CAnvDoc (CDocument) and CAnvView (CFormView) classes. I have mixed yours examples MIDIDOCVIEW and FormView from StatusPanes. When I comile my example I get the following error when CAnvView is done. 1>c:\program files (x86)\foss software inc\prof-uis\include\exttempl.h(306) :
error C2664: ’CExtAFV<CExtAFVBase>::CExtAFV(__EXT_MFC_SAFE_LPCTSTR,CWnd *)’ : cannot convert parameter1 from ’UINT’ to ’__EXT_MFC_SAFE_LPCTSTR’ What have I done wrong? My class declaration begins with.. ---------- #pragma once
#ifdef IMPL_DANV
#define CLASS_DECL_DANV _declspec(dllexport)
#else
#define CLASS_DECL_DANV _declspec(dllimport)
#endif
#include "ExtButton.h"
class CAnvDoc;
// CAnvView
class CLASS_DECL_DANV CAnvView
: public CExtWA < CExtWS < CExtAFV < CFormView > > >
{
protected: // create from serialization only
CAnvView();
DECLARE_DYNCREATE(CAnvView)
// Form Data
public:
//{{AFX_DATA(CArtView)
enum { IDD = IDD_DEDU_AAA };
CExtButton m_ctlOk;
//}}AFX_DATA
-------------------- and the cpp-file begins with: #include "stdafx.h"
#include "DAnv.h"
#include "Dedu.h"
#include "AnvFrame.h"
#include "AnvDoc.h"
#include "AnvView.h"
// CAnvView
IMPLEMENT_DYNAMIC(CAnvView, CFormView)
CAnvView::CAnvView()
: CExtWA < CExtWS < CExtAFV < CFormView > > > ( CAnvView::IDD, ((CWnd *)NULL) )
{
}
CAnvView::~CAnvView()
{
}
-------------------
|
|
Technical Support
|
Nov 5, 2009 - 1:31 PM
|
You faced a Visual C++ bug related to the incorrect exporting of template based classes. The solution is tricky. You need to declare one additional non-exported class:
class /* not exported-imported */ CDllInternalFormViewClass : public CExtWA < CExtAFV < CFormView > >
{
. . .
};
class CLASS_DECL_DANV CAnvView : public CDllInternalFormViewClass
{
. . .
};
Your CAnvView will need to implement all the virtual methods present in the CDllInternalFormViewClass class.
|
|
cosmin dumitru
|
Nov 5, 2009 - 4:00 AM
|
Hi, I try to compile prof-uis lib 2.87 - statsic unicode with mcs dll, with __EXT_MFC_ENABLE_TEMPLATED_CHARS set and also #define __EXT_MFC_COMPILED_WITH_NATIVE_WCHAR_T #define __EXT_MFC_TEMPLATED_CHARS_IMPLEMENTED
i got \Include\ExtEdit.h(226) : error C2440: ’type cast’ : cannot convert from ’__EXT_MFC_SAFE_LPTSTR’ to ’LPINT’
1> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>..\Src\ExtEdit.cpp(2426) : error C2593: ’operator +=’ is ambiguous
1> ..\Include\ExtMfcSafeNativeTCHAR.h(4239): could be ’CExtSafeStringW &CExtSafeStringW::operator +=(__prof_uis_converted_wchar_t)’
1> ..\Include\ExtMfcSafeNativeTCHAR.h(4234): or ’CExtSafeStringW &CExtSafeStringW::operator +=(__prof_uis_used_wchar_t)’
1> while trying to match the argument list ’(CExtSafeString, __EXT_MFC_SAFE_TCHAR)’
1>..\Src\ExtEdit.cpp(2449) : error C2678: binary ’!’ : no operator found which takes a left-hand operand of type ’__EXT_MFC_SAFE_TCHAR’ (or there is no acceptable conversion)
1> could be ’built-in C++ operator!(bool)’
1> while trying to match the argument list ’(__EXT_MFC_SAFE_TCHAR)’ any ideeas ? regards
|
|
Technical Support
|
Nov 6, 2009 - 2:07 PM
|
We received your e-mail and replied with the fix information.
|
|
tera tera
|
Nov 5, 2009 - 12:59 AM
|
|
|
Technical Support
|
Nov 9, 2009 - 1:18 PM
|
Please update the source code for the following method:
LRESULT CALLBACK CExtPopupMenuSite::_HookMouseProc(
int nCode, // hook code
WPARAM wParam, // message identifier
LPARAM lParam // mouse coordinates
)
{
__PROF_UIS_MANAGE_STATE;
if( nCode != HC_ACTION )
return
::CallNextHookEx(
g_DefPopupMenuSite.m_hMouseHook,
nCode,
wParam,
lParam
);
MOUSEHOOKSTRUCT* lpMS = (MOUSEHOOKSTRUCT*)lParam;
ASSERT( lpMS != NULL );
if( CExtPopupMenuWnd::TEAROFFNOTIFICATON::g_pCurrentTEAROFFNOTIFICATON != NULL )
{
switch( wParam )
{
case WM_MOUSEMOVE:
{
CPoint pt( lpMS->pt );
if( CExtPopupMenuWnd::TEAROFFNOTIFICATON::g_pCurrentTEAROFFNOTIFICATON->
_OnMouseMove(
(UINT)wParam,
pt
)
)
return 1; // eat!
}
break;
case WM_MOUSEWHEEL:
{
if( CExtPopupMenuWnd::TEAROFFNOTIFICATON::g_pCurrentTEAROFFNOTIFICATON->
_OnMouseWheel(
wParam,
lParam
)
)
return 1; // eat!
}
break;
case WM_NCLBUTTONDOWN:
case WM_NCRBUTTONDOWN:
case WM_NCMBUTTONDOWN:
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_NCLBUTTONUP:
case WM_NCRBUTTONUP:
case WM_NCMBUTTONUP:
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
{
CPoint ptSrc( lpMS->pt );
if( CExtPopupMenuWnd::TEAROFFNOTIFICATON::g_pCurrentTEAROFFNOTIFICATON->_OnMouseClick(
(UINT)wParam,
ptSrc
)
)
return 1; // eat!
}
break;
} // switch( wParam )
}
if( nCode == HC_ACTION // +2.55 - fix by Ulrich Berger-Kubik
&& (! g_DefPopupMenuSite.IsEmpty() )
&& (! g_DefPopupMenuSite.IsShutdownMode() )
)
{
CExtPopupMenuWnd * pWndCapture =
g_DefPopupMenuSite.GetCapture();
if( pWndCapture != NULL
&& ::IsWindow( pWndCapture->GetSafeHwnd() )
)
{
ASSERT_VALID( pWndCapture );
CExtBarButton * pSavedTrackingMenuTBB = CExtBarButton::g_pTrackingMenuTBB;
switch( wParam )
{
//case WM_MOUSEACTIVATE:
// if( lpMS->hwnd != pWndCapture->GetSafeHwnd() )
// return 1;
//break;
case WM_MOUSEMOVE:
{
CPoint pt( lpMS->pt );
pWndCapture->ScreenToClient( &pt );
bool bNoEat = false;
if( pWndCapture->
_OnMouseMove(
(UINT)wParam,
pt,
bNoEat
)
)
{
HWND hWnd = ::WindowFromPoint( lpMS->pt );
if( hWnd != NULL
&& ::GetWindowThreadProcessId( hWnd, NULL ) == ::GetCurrentThreadId()
)
{
INT nHT = (INT)::SendMessage( hWnd, WM_NCHITTEST, 0L, MAKELPARAM(lpMS->pt.x,lpMS->pt.y) );
INT nMM = WM_MOUSEMOVE;
if( nHT != HTCLIENT
&& nHT != HTMINBUTTON
&& nHT != HTMAXBUTTON
&& nHT != HTHELP
&& nHT != HTCLOSE
&& nHT != HTNOWHERE
)
nMM = WM_NCMOUSEMOVE;
else
nHT = HTCLIENT;
::SendMessage( hWnd, WM_SETCURSOR, (WPARAM)hWnd, MAKELPARAM(nHT,nMM) );
}
return 1; // eat!
}
if( bNoEat )
return
::CallNextHookEx(
g_DefPopupMenuSite.m_hMouseHook,
nCode,
wParam,
lParam
);
}
break;
case WM_MOUSEWHEEL:
{
bool bNoEat = false;
if( pWndCapture->
_OnMouseWheel(
wParam,
lParam,
bNoEat
)
)
return 1; // eat!
if( bNoEat )
return
::CallNextHookEx(
g_DefPopupMenuSite.m_hMouseHook,
nCode,
wParam,
lParam
);
return 1; // eat!
}
break;
case WM_NCLBUTTONDBLCLK:
case WM_NCRBUTTONDBLCLK:
case WM_NCMBUTTONDBLCLK:
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
case WM_MBUTTONDBLCLK:
CExtBarButton::g_pTrackingMenuTBB = NULL;
// continue ...
case WM_NCLBUTTONDOWN:
case WM_NCRBUTTONDOWN:
case WM_NCMBUTTONDOWN:
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_NCLBUTTONUP:
case WM_NCRBUTTONUP:
case WM_NCMBUTTONUP:
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
{
HWND hWndFromPoint = WindowFromPoint( lpMS->pt );
LRESULT nHT =
::SendMessage(
hWndFromPoint,
WM_NCHITTEST,
0L,
MAKELPARAM( lpMS->pt.x, lpMS->pt.y )
);
if( hWndFromPoint != NULL )
{
if( ( nHT == HTSYSMENU || nHT == HTCAPTION )
&& wParam != WM_NCLBUTTONUP
&& ( ! g_PaintManager.m_DWM.IsCompositionEnabled() )
)
{
CWnd * pWndFromPointPermanent = CWnd::FromHandlePermanent( hWndFromPoint );
if( pWndFromPointPermanent == NULL
|| (! pWndFromPointPermanent->IsKindOf( RUNTIME_CLASS(CMiniFrameWnd) ) )
)
{
pWndCapture->TrackFlagsSet( pWndCapture->TrackFlagsGet() | TPMX_NO_FADE_OUT_ANIMATION );
CExtToolControlBar::_CloseTrackingMenus();
CExtPopupMenuWnd::CancelMenuTracking();
return
::CallNextHookEx(
g_DefPopupMenuSite.m_hMouseHook,
nCode,
wParam,
lParam
);
}
}
} // if( hWndFromPoint != NULL )
//CRect rcWndCapture;
//_pWndCapture->GetWindowRect( &rcWndCapture );
//if( !rcWndCapture.PtInRect(lpMS->pt) )
// break;
CPoint ptSrc( lpMS->pt );
pWndCapture->ScreenToClient( &ptSrc );
bool bSameToolBarButtonIsClicked = false;
CExtPopupMenuWnd * pDefInstancePopup = CExtPopupMenuSite::g_DefPopupMenuSite.GetInstance();
CPoint pt( lpMS->pt );
HWND hWndPT = ::WindowFromPoint( pt );
CWnd * pWndPermanentPT = NULL;
if( hWndPT != NULL )
pWndPermanentPT = CWnd::FromHandlePermanent( hWndPT );
if( pDefInstancePopup != NULL
&& pWndPermanentPT != NULL
&& pSavedTrackingMenuTBB != NULL
&& ( wParam == WM_LBUTTONDOWN || wParam == WM_LBUTTONDBLCLK )
)
{
ASSERT_VALID( pDefInstancePopup );
ASSERT( ::IsWindow(pDefInstancePopup->GetSafeHwnd()) );
if( ( ! pDefInstancePopup->m_rcExcludeArea.IsRectEmpty() )
&& pDefInstancePopup->m_rcExcludeArea.PtInRect( pt )
&& pWndPermanentPT != NULL
&& pWndPermanentPT->IsKindOf( RUNTIME_CLASS( CExtToolControlBar ) )
)
{
CPoint ptBarClient = pt;
pWndPermanentPT->ScreenToClient( &ptBarClient );
INT nHtTbb = ((CExtToolControlBar*)pWndPermanentPT)->HitTest( ptBarClient );
if( nHtTbb >= 0 && LPVOID(((CExtToolControlBar*)pWndPermanentPT)->GetButton(nHtTbb)) == LPVOID(pSavedTrackingMenuTBB) )
bSameToolBarButtonIsClicked = true;
}
}
DWORD dwCTF = pWndCapture->TrackFlagsGet();
bool bNoEat = false;
HWND hWndCapture = pWndCapture->GetSafeHwnd();
ASSERT( hWndCapture != NULL && ::IsWindow(hWndCapture) );
if( pWndCapture->_OnMouseClick(
(UINT)wParam,
ptSrc,
bNoEat
)
)
{
if( ( ! bNoEat )
&& ( dwCTF & TPMX_SYSMENU ) != 0
&& ( wParam == WM_NCLBUTTONDOWN || wParam == WM_NCLBUTTONDBLCLK )
&& nHT == HTSYSMENU
)
return
::CallNextHookEx(
g_DefPopupMenuSite.m_hMouseHook,
nCode,
wParam,
lParam
);
if( ! bSameToolBarButtonIsClicked )
return 1; // eat!
}
if( ( ! bNoEat )
&& ( dwCTF & TPMX_SYSMENU ) != 0
&& ( wParam == WM_NCLBUTTONDOWN || wParam == WM_NCLBUTTONDBLCLK )
&& nHT == HTSYSMENU
)
bNoEat = true;
if( bNoEat )
return
::CallNextHookEx(
g_DefPopupMenuSite.m_hMouseHook,
nCode,
wParam,
lParam
);
if( ! (::IsWindow(hWndCapture)) )
return 1; // eat!
// post processing
if( hWndPT != NULL )
{
CExtPopupMenuWnd * pPopup = pWndCapture;
for( ; pPopup != NULL; pPopup = pPopup->m_pWndParentMenu )
{
CPoint ptClient( pt );
pPopup->ScreenToClient( &ptClient );
if( pPopup->_PtInWndArea(ptClient) )
return 1; // eat!
CExtPopupMenuTipWnd & _tipWnd = pPopup->GetTip();
HWND hWndTest = _tipWnd.GetSafeHwnd();
if( hWndTest != NULL )
{
if( hWndTest == hWndPT
|| ::IsChild( hWndTest, hWndPT )
)
return 1; // eat!
} // if( hWndTest != NULL )
if( pWndPermanentPT != NULL
&& ::IsChild( pPopup->m_hWnd, hWndPT )
&& pWndPermanentPT->IsKindOf( RUNTIME_CLASS(CScrollBar) )
)
return 1; // eat!
} // for( ; pPopup != NULL; pPopup = pPopup->m_pWndParentMenu )
} // if( hWndPT != NULL )
if( pDefInstancePopup != NULL )
{
bool bEatEvent = false;
ASSERT_VALID( pDefInstancePopup );
ASSERT( ::IsWindow(pDefInstancePopup->GetSafeHwnd()) );
if( bSameToolBarButtonIsClicked )
bEatEvent = true;
pDefInstancePopup->_CancelingSet();
pDefInstancePopup->_OnCancelMode();
if( ! bEatEvent )
{
if( wParam != WM_LBUTTONDOWN
&& wParam != WM_RBUTTONDOWN
&& wParam != WM_MBUTTONDOWN
)
bEatEvent = true;
}
if( ! bEatEvent )
{
if( ! ::IsWindow( hWndPT ) )
bEatEvent = true;
}
if( bEatEvent )
{
if( CExtPopupMenuWnd::g_bEatNcAreaClicks )
return 1; // eat!
}
} // if( pDefInstancePopup != NULL )
// else
// CExtPopupMenuSite::g_DefPopupMenuSite._Done();
}
break;
//default:
// return 1; // eat!
} // switch( wParam )
} // if( pWndCapture != NULL ....
else
return 1; // eat
} // if( (! g_DefPopupMenuSite.IsEmpty() ) ...
return
::CallNextHookEx(
g_DefPopupMenuSite.m_hMouseHook,
nCode,
wParam,
lParam
);
}
|
|
tera tera
|
Nov 8, 2009 - 6:01 PM
|
|
|
Rado Manzela
|
Nov 4, 2009 - 6:38 AM
|
Is there some function in CExtResizableDialog to save it’s size and position into registry, like CExtControlBar::ProfileBarStateSave for frame wnd? I can’t find it. Thank you.
|
|
Technical Support
|
Nov 4, 2009 - 9:13 AM
|
You should invoke the EnableSaveRestore() method near the end of your dialog’s OnInitDialog() virtual method.
|
|
Rado Manzela
|
Nov 4, 2009 - 12:27 PM
|
|
|
tera tera
|
Nov 4, 2009 - 1:36 AM
|
Hello. http://www.prof-uis.com/prof-uis/tech-support/support-forum/glass-window-question-65732.aspx In m_DWM.DwmDefWindowProc, I cannot judge HT**.
Therefore, it seems to be the following and should describe what program? g_PaintManager.m_DWM.DwmDefWindowProc(
hWnd,
message, // WM_NCHITTEST
wParam,
lParam,
&lResult
)
); lr = DefWindowProc ( message , wParam , lParam );
switch ( lr ){
case HTCLIENT:
case HTSYSMENU: //
case HTMAXBUTTON: //
case HTMINBUTTON: //
return 1;
break;
}
|
|
Technical Support
|
Nov 8, 2009 - 11:25 AM
|
|
|
tera tera
|
Nov 4, 2009 - 5:45 PM
|
Please answer it.
Are you busy with 2.87 development?
|
|
tera tera
|
Nov 5, 2009 - 5:24 PM
|
Development does not advance.
Please answer it
|
|
howard liu
|
Nov 3, 2009 - 2:06 AM
|
Dear support, The app works fine with IDE VS2003 and PROFUIS285 libs, but after upgrading the IDE from VS2003 to VS2005, when launching the app, the Main document Window appears, but it keeps refreshing without responding to any mouse click event, except ’minimize’, ’maximize’, and ’close’ icon in the top right corner. When debugging into the app, it shows the ’CWnd::OnActivateApp’ was being invoked repeatedly by mfc framework, which was invoked by PROFUIS285d.dll (ExtHook.cpp, LRESULT HookChainsWindowProc(
UINT nMessage,
WPARAM & wParam,
LPARAM & lParam
)) has anyone experienced similar UI refreshing problem before ? Any idea what’s the cause of this and how to fix it? Thank you.
|
|
Technical Support
|
Nov 4, 2009 - 2:58 AM
|
The call stack listing looks like normal handling of the WM_ACTIVATEAPP standard message by the main frame window. But it looks like only at a glance. The call stack listing seems incomplete or corrupted. The CExtGridJoinManager::OnColumnRemoved() method cannot be at the bottom of the stack and the WinMainCRTStartup() . If you are using Prof-UIS, then you definitively don’t need classes like CCoolMenuManager and CSubclassWnd . How long time ago did you rebuild your project and all its modules completely from scratch? Do you use any other components and/or libraries which perform UI skinning, especially window non-client area skinning?
|
|
howard liu
|
Nov 3, 2009 - 6:08 PM
|
Vector NTI 10.exe!CMainFrame::OnActivateApp(int bActive=1, unsigned long hTask=5536) Line 3791 C++ mfc80d.dll!CWnd::OnWndMsg(unsigned int message=28, unsigned int wParam=1, long lParam=5536, long * pResult=0x0006f55c) Line 2036 C++ mfc80d.dll!CWnd::WindowProc(unsigned int message=28, unsigned int wParam=1, long lParam=5536) Line 1741 + 0x20 bytes C++ Vector NTI 10.exe!CExtNCW<CMDIFrameWnd>::WindowProc(unsigned int message=28, unsigned int wParam=1, long lParam=5536) Line 475 + 0x14 bytes C++ mfc80d.dll!AfxCallWndProc(CWnd * pWnd=0x039e5d70, HWND__ * hWnd=0x00330e36, unsigned int nMsg=28, unsigned int wParam=1, long lParam=5536) Line 240 + 0x1c bytes C++ mfc80d.dll!AfxWndProc(HWND__ * hWnd=0x00330e36, unsigned int nMsg=28, unsigned int wParam=1, long lParam=5536) Line 389 C++ mfc80d.dll!AfxWndProcBase(HWND__ * hWnd=0x00330e36, unsigned int nMsg=28, unsigned int wParam=1, long lParam=5536) Line 411 + 0x15 bytes C++ user32.dll!7e418734() [Frames below may be incorrect and/or missing, no symbols loaded for user32.dll] user32.dll!7e418816() user32.dll!7e42a013() user32.dll!7e42a998() ProfUIS285md.dll!CExtHookSink::HookChains_t::HookChainsWindowProc(unsigned int nMessage=28, unsigned int & wParam=1, long & lParam=5536) Line 227 + 0x20 bytes C++ ProfUIS285md.dll!CExtHookSink::HookChains_t::g_HookWndProc(HWND__ * hWnd=0x00330e36, unsigned int nMessage=28, unsigned int wParam=1, long lParam=5536) Line 291 + 0x14 bytes C++ user32.dll!7e418734() user32.dll!7e418816() user32.dll!7e42a013() user32.dll!7e42a998() VectorNTIUtils.dll!CSubclassWnd::WindowProc(unsigned int msg=28, unsigned int wp=1, long lp=5536) Line 91 + 0x5e bytes C++ VectorNTIUtils.dll!CCoolMenuManager::WindowProc(unsigned int msg=28, unsigned int wp=1, long lp=5536) Line 427 C++ VectorNTIUtils.dll!HookWndProc(HWND__ * hwnd=0x00330e36, unsigned int msg=28, unsigned int wp=1, long lp=5536) Line 145 + 0x1b bytes C++ user32.dll!7e418734() user32.dll!7e418816() user32.dll!7e428ea0() user32.dll!7e428eec() ntdll.dll!7c90e473() user32.dll!7e4193e9() user32.dll!7e4193a8() user32.dll!7e42a43b() mfc80d.dll!CWinThread::Run() Line 636 + 0x15 bytes C++ mfc80d.dll!CWinApp::Run() Line 894 C++ Vector NTI 10.exe!AfxWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x00091f15, int nCmdShow=1) Line 1174 + 0xd bytes C++ Vector NTI 10.exe!WinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x00091f15, int nCmdShow=1) Line 33 C++ Vector NTI 10.exe!__tmainCRTStartup() Line 589 + 0x35 bytes C Vector NTI 10.exe!WinMainCRTStartup() Line 414 C kernel32.dll!7c817077() Vector NTI 10.exe!std::vector<CRSite *,std::allocator<CRSite *> >::~vector<CRSite *,std::allocator<CRSite *> >() Line 547 + 0xf bytes C++ Vector NTI 10.exe!std::vector<CRSite *,std::allocator<CRSite *> >::~vector<CRSite *,std::allocator<CRSite *> >() Line 547 + 0xf bytes C++ Vector NTI 10.exe!CGeneralOptionsPage::DoDataExchange(CDataExchange * pDX=0x00780053) Line 337 C++ Vector NTI 10.exe!std::vector<CRSite *,std::allocator<CRSite *> >::~vector<CRSite *,std::allocator<CRSite *> >() Line 547 + 0xf bytes C++ ProfUIS285md.dll!CExtGridJoinManager::OnColumnRemoved(unsigned long nColNo=, unsigned long nColCount=, CExtGridDataProvider & _DP=) Line 48456 + 0x15 bytes C++
The call stack was listed above, the OnActivateApp was kept invoking which keeps refreshing the main UI. I did not try with other Prof-UIS sample apps.
|
|
Technical Support
|
Nov 3, 2009 - 12:59 PM
|
Please provide us with a call stack listing. Is it possible to reproduce this issue with any of Prof-UIS sample applications?
|
|
Rolf Boerkoel
|
Nov 2, 2009 - 8:52 AM
|
Dear support, I have an MDI application with tabs to manage the childframes (CExtTabMdiWnd and friends). ProfUIS 2.87 latest snapshot. If I change the title of some CDocument, the new document name is not repainted automatically in the tab labels. Only after forcing an invalidation of the tab control area (by moving the mouse over, by minimizing/maximizing etc.) the new name gets repainted.
You can see this same behaviour in e.g. the form-editor sample application. Start the application, select File / Save As..., enter some new name and notice that the label text in the tab control remains the same. I can of course get by this problem by doing something like : AfxGetMainWnd()->PostMessage(WM_APP_INVALIDATEMDITABS) ... void CMainFrame::OnInvalidateMdiTabs() { m_mdiTabWindow.Invalidate(); }
on every occasion a document title might be changed. In fact I am doing this right now. But this feels a bit like a clumsy workaround. Is there a possibility that you can invalidate MDI tab controls automatically from somewhere within the Prof-UIS library? Kind Regards, Marco
|
|
Rolf Boerkoel
|
Nov 4, 2009 - 2:14 AM
|
No, actually I meant CExtTMWI<CExtTabWnd>::_SyncAllItems(). I’ll send you a minimal sample application by email.
In this sample I can close the documents without any problems, strangely enough. However it DOES go wrong if I switch to another doc/view by clicking on the tabs. Exact the same assertion is raised as in our application; the stack trace looks very similar.
Here’s a piece of this stack trace: (...)
__crtMessageBoxA(const char * 0x0012b6a4, const char * 0x102579a0 `string’, unsigned int 73746) line 65
CrtMessageWindow(int 2, const char * 0x00c833a0 THIS_FILE, const char * 0x0012c7d8, const char * 0x00000000, const char * 0x0012e7fc) line 520 + 22 bytes
_CrtDbgReport(int 2, const char * 0x00c833a0 THIS_FILE, int 948, const char * 0x00000000, const char * 0x00000000) line 419 + 76 bytes
AfxAssertFailedLine(const char * 0x00c833a0 THIS_FILE, int 948) line 39 + 20 bytes
CExtTabWnd::AssertValid() line 948 + 47 bytes
CExtTabMdiWnd::AssertValid() line 6478
AfxAssertValidObject(const CObject * 0x018cf574 {CExtTabMdiWnd}, const char * 0x00c833a0 THIS_FILE, int 4943) line 108
CExtTabWnd::OnTabWndRemoveItem(long 2, long 1, unsigned char 0) line 4947
CExtTMWI<CExtTabWnd>::OnTabWndRemoveItem(long 2, long 1, unsigned char 0) line 1988
CExtTabWnd::ItemRemove(long 2, long 1, unsigned char 0) line 1709 + 26 bytes
CExtTMWI<CExtTabWnd>::_SyncAllItems() line 1330
CExtTMWI<CExtTabWnd>::WindowProc(unsigned int 275, unsigned int 3, long 0) line 2144 + 16 bytes
AfxCallWndProc(CWnd * 0x018cf574 {CExtTabMdiWnd hWnd=???}, HWND__ * 0x00140502, unsigned int 275, unsigned int 3, long 0) line 215 + 26 bytes
AfxWndProc(HWND__ * 0x00140502, unsigned int 275, unsigned int 3, long 0) line 368
AfxWndProcBase(HWND__ * 0x00140502, unsigned int 275, unsigned int 3, long 0) line 220 + 21 bytes
(...) CExtTabWnd::AssertValid() is triggered because m_nVisibleItemCount (=3) becomes bigger than nItemCount (=2). As I mentioned before, the problem is not present if the update is delayed by posting a WM_TIMER message.
I also noticed that if I leave out the CExtNCB from the CMdiFrameWnd the problem also does not occur.
Marco
|
|
Technical Support
|
Nov 9, 2009 - 1:23 PM
|
Dear Marco,
Thank you for providing us with the test project. To fix the MDI tabs assertion issue please update the source code for the CExtTMWI::_SyncAllItems() method:
virtual bool _SyncAllItems()
{
if( m_nSyncCounter < m_nSyncWaitCount )
{
m_nSyncCounter++;
return false;
}
if( m_bInSyncLayout || _IsDND() )
return true;
m_bInSyncLayout = true;
CWnd * pWndActiveMdiChild = NULL;
HWND hWndMainFrame = _GetHwndMainFrame();
HWND hWndMdiArea = _GetHwndMdiArea();
if( hWndMainFrame == NULL
|| hWndMdiArea == NULL
)
{
m_bInSyncLayout = false;
return true;
}
CMDIFrameWnd * pMdiFrame =
DYNAMIC_DOWNCAST(
CMDIFrameWnd,
CWnd::FromHandlePermanent(hWndMainFrame)
);
if( pMdiFrame != NULL )
{
pWndActiveMdiChild = pMdiFrame->MDIGetActive(NULL);
} // if( pMdiFrame != NULL )
else
{
HWND hWnd = (HWND)
::SendMessage(
hWndMdiArea,
WM_MDIGETACTIVE,
0,
0
);
if( hWnd == NULL )
{
m_bInSyncLayout = false;
return true;
}
pWndActiveMdiChild = CWnd::FromHandle( hWnd );
} // else from if( pMdiFrame != NULL )
if( pWndActiveMdiChild == NULL )
{
m_bInSyncLayout = false;
return true;
}
bool bCloseEnabled = false;
HWND hWndMdiChild = NULL;
if( pWndActiveMdiChild != NULL )
{
hWndMdiChild =
pWndActiveMdiChild->
GetWindow( GW_HWNDFIRST )->
GetSafeHwnd();
CMenu * pSysMenu = pWndActiveMdiChild->GetSystemMenu( FALSE );
if( pSysMenu != NULL )
{
MENUITEMINFO mii;
::memset(&mii,0,sizeof(MENUITEMINFO));
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_STATE;
if( pSysMenu->GetMenuItemInfo(
SC_CLOSE,
&mii,
FALSE
)
)
{
if( ( mii.fState & (MFS_DISABLED|MFS_GRAYED) ) == 0 )
bCloseEnabled = true;
}
}
}
ModifyTabWndStyle(
bCloseEnabled ? 0 : __ETWS_ENABLED_BTN_CLOSE,
bCloseEnabled ? __ETWS_ENABLED_BTN_CLOSE : 0,
false
);
for( ; hWndMdiChild != NULL; hWndMdiChild = ::GetWindow( hWndMdiChild, GW_HWNDNEXT ) )
{
LONG nIndexExist = ItemFindByHWND( hWndMdiChild, -1, true, true );
if( nIndexExist >= 0 )
{
if( hWndMdiChild == pWndActiveMdiChild->GetSafeHwnd() )
SelectionSet( nIndexExist, true, false );
continue;
}
ItemInsert(
NULL,
NULL, false,
0,
-1,
LPARAM( hWndMdiChild ),
false
);
if( hWndMdiChild == pWndActiveMdiChild->GetSafeHwnd() )
SelectionSet( ItemGetCount()-1, true, false );
} // for( ; hWndMdiChild != NULL; hWndMdiChild = ::GetWindow( hWndMdiChild, GW_HWNDNEXT ) )
m_nVisibleItemCount = 0L;
for( INT nIndex = 0; nIndex < ItemGetCount(); )
{
TAB_ITEM_INFO * pTii = ItemGet( nIndex );
ASSERT_VALID( pTii );
HWND hWnd = (HWND)pTii->LParamGet();
ASSERT( hWnd );
if( ::IsWindow( hWnd ) )
{
if( hWnd == pWndActiveMdiChild->m_hWnd
&& (!bCloseEnabled)
)
pTii->ModifyItemStyleEx( 0, __ETWI_EX_NO_CLOSE_ON_TAB );
bool bVisible = ::IsWindowVisible( hWnd ) ? true : false;
pTii->VisibleSet( bVisible );
nIndex++;
}
else
ItemRemove( nIndex );
}
m_bInSyncLayout = false;
bool bLayoutUpdated = _RecalcFrameLayout();
Invalidate();
return bLayoutUpdated;
}
|
|
Rolf Boerkoel
|
Nov 10, 2009 - 2:36 AM
|
It looks like the problem is solved with this fix. Thanks.
|
|
Technical Support
|
Nov 2, 2009 - 11:14 AM
|
The MDI tab window hooks the standard MDI interface and updates tab items automatically when catching any messages affecting to captions of MDI child frame windows. But the document title is just a text property of MFC document that is not HWND -based component and does not receive any messages. That’s why manual updating of the MDI tab window is required. You should invoke the UpdateTabWnd() method of MDI tabs control after changing document’s title.
|
|
Rolf Boerkoel
|
Nov 3, 2009 - 2:46 AM
|
Ok, got it. In the meantime I changed the redraw mechanism by overriding CMDIFrameWnd::OnUpdateFrameTitle which seems to work fine.
void CMainFrame::OnUpdateFrameTitle(BOOL bAddToTitle)
{
CMDIFrameWnd::OnUpdateFrameTitle(bAddToTitle);
m_myExtMdiTabWindow.UpdateTabWnd();
} After a google search I found that this question has been asked before on this forum. It might be illustrative for other ProfUIS users if you include a similar solution in the sample applications, because these samples also do not redraw their tabs when a document title changes.
|
|
Rolf Boerkoel
|
Nov 3, 2009 - 4:35 AM
|
Perhaps calling UpdateTabWnd directly from OnUpdateFrameTitle is not a good idea, it makes my application crash somewhere in CExtTabMdiWnd::_SyncAllItems() when a document is closed when two or more documents are active.
A delayed update however always works fine: void CMainFrame::OnUpdateFrameTitle(BOOL bAddToTitle)
{
CMDIFrameWnd::OnUpdateFrameTitle(bAddToTitle);
m_myExtMdiTabWindow.PostMessage(WM_TIMER, __EXTTAB_MDI_UPDATE_TIMER_ID, 0);
} (using the same trick as you do).
|
|
Technical Support
|
Nov 3, 2009 - 1:00 PM
|
We guess you meant the CExtPopupMenuWnd::_SyncItems() method. Could you please provide us with a call stack listing at the crash time and exact crash location in the source code of the _SyncItems() method?
|
|
Bertil Morefält
|
Nov 2, 2009 - 5:57 AM
|
Hi! I have an application with 28 dll:s (MFC Extenstion DLL:s) and I am trying to bild a new MFC Extenstin DLL where I use yours ProfUIS 2.85. When I comile the DLL only, there is no error but when I in my App:s InitInstance add my doc/view to AddDocTemplate and compile my application I receive the following error: 2>c:\dedu.net\danv\anvframe.h(10) : error C2504: ’CExtNCW’ : base class undefined
2>c:\dedu.net\danv\anvframe.h(10) : error C2143: syntax error : missing ’,’ before ’<’ It seems thet CExtNCW does not exist, why? I have included #include < Prof-UIS.h > // Prof-UIS library in stdfax.h for my DLL but not in my main application. Best regards, Bertil Morefält
|
|
Technical Support
|
Nov 2, 2009 - 9:09 AM
|
If your extension DLLs do export of any Prof-UIS-based classes including template-based, then your main EXE project should also include Prof-UIS.h file in its StdAfx.h file. The CExtNCW class is the template class from Prof-UIS. We suspect some of your extension DLLs exports some CExtNCW -based class.
|
|
tera tera
|
Nov 2, 2009 - 1:10 AM
|
Hello. question 1, When prof-uis version up, do the "Prof-UIS (v2.8.7.0)-control-bar-state-data" become incompatible? question 2, I add Z Bar to application newly
Then, I start application.
In application, I read existing "Prof-UIS (v2.8.7.0)-control-bar-state-data". (The information of the Z-bar is not included ) Is not there the problem in such how to use?
|
|
Technical Support
|
Nov 9, 2009 - 1:20 PM
|
The state data must be completely synchronized with simple resizable bars created inside the main frame window. This is the required condition. To avoid it, we created dynamic resizable bars.
|
|
tera tera
|
Nov 10, 2009 - 12:34 AM
|
Hello. I am going to replace the variable declaration of the bar with CExtDynamicControlBar from CExtContorlBar. Is there any problem?
|
|
Technical Support
|
Nov 10, 2009 - 2:46 PM
|
Dynamic bars are always dynamically allocated pointers and controlled by dynamic bar site. You should derived your main frame class from dynamic bar site and allocate required bars. See the SDI_DynamicBars / MDI_DynamicBars sample projects for details.
|
|
Technical Support
|
Nov 2, 2009 - 9:09 AM
|
The bar state data format was not changed in Prof-UIS 2.87. All the CExtControlBar windows from 2.87 have compatible state data format. But we added support for tab page order saving/restoring for dynamic resizable control bars (CExtDynamicControlBar ) in the document mode in SDI applications with tab page container window as the main view window. These dynamic bars have compatible format for migrating from 2.85 to 2.87 but not vice versa. If you need to create some bars dynamically, then you should use CExtDynamicControlBar bars which allow you to allocate/free any bars anytime. The CExtControlBar bars require exact matching between state data and bars created inside the frame window.
|
|
tera tera
|
Nov 3, 2009 - 6:18 PM
|
In CExtControlBar-bars, I have programed all.
With CExtControlBar-ProfileBarStateSerialize, I transform the positional information of the bar. It is difficult to change a program of it to DynBar now. .....
|
|
tera tera
|
Nov 4, 2009 - 7:44 PM
|
|
|
Borremans Pierre
|
Nov 2, 2009 - 1:02 AM
|
How to change the color o the menu and the statusbar ? I overdrive the class CExtPaintManagerOffice2007_R2_Obsidian but which value I must change ?
|
|
Technical Support
|
Nov 5, 2009 - 2:50 AM
|
This can be done by overriding the CExtPaintManager::PaintMenuItem() virtual method. Change the CExtPaintManager::PAINTMENUITEMDATA::m_clrForceMenuText value. Invoke the parent class method with modified value.
Override the CExtPaintManager::StatusBar_PaintPane() virtual method and invoke the parent class method with a desired text color value.
|
|
Technical Support
|
Nov 2, 2009 - 11:13 AM
|
The CExtPaintManager::PaintMenuItem() virtual method uses a reference to the CExtPaintManager::PAINTMENUITEMDATA data structure as a parameter. The CExtPaintManager::PAINTMENUITEMDATA::m_clrForceMenuText property allows you to change the menu text color. The CExtPaintManager::StatusBar_PaintPane() virtual method draws the status bar pane. The clrText parameter of this method specifies the text color. You can override these virtual methods and invoke the parent class methods with specifying required text colors.
|
|
Borremans Pierre
|
Nov 4, 2009 - 1:12 AM
|
thanks for your answer but how to modifiy the background color ?
|
|
Borremans Pierre
|
Nov 30, 2009 - 8:54 AM
|
ok and how to change the text color of the header item in my main menu ?
|
|
Technical Support
|
Nov 30, 2009 - 1:31 PM
|
The top level menu is the menu bar. This is the CExtMenuControlBar class in Prof-UIS. The CExtMenuControlBar menu bar control is based on the CExtToolControlBar toolbar control. The menu bar implements the top menu level as a set of toolbar items with submenus. The toolbar/menu bar buttons are instances of the CExtBarButton objects. You need to code your CExtBarButton -derived class which paints text using some preferred text color and make the menu bar using your toolbar buttons. Here is how your menu bar button class should look like:
class CYourMenuBarButton : public CExtBarButton
{
public:
CYourMenuBarButton(
CExtToolControlBar * pBar = NULL,
UINT nCmdID = ID_SEPARATOR,
UINT nStyle = 0
)
: CExtBarButton( pBar, nCmdID, nStyle )
{
}
virtual ~CYourMenuBarButton()
{
}
void CExtBarButton::PaintCompound(
CDC & dc,
bool bPaintParentChain,
bool bPaintChildren,
bool bPaintOneNearestChildrenLevelOnly
)
{
ASSERT_VALID( this );
ASSERT_VALID( (&dc) );
ASSERT( dc.GetSafeHdc() != NULL );
CExtToolControlBar * pBar = GetBar();
ASSERT_VALID( pBar );
if( ! IsPaintAble( dc ) )
return;
if( AnimationClient_StatePaint( dc ) )
return;
if( bPaintParentChain )
PaintParentChain( dc );
CWnd * pCtrl = CtrlGet();
if( ( pCtrl != NULL )
&& ( ( ! m_bVertDocked )
|| GetCtrlVisibleVertically()
)
)
return;
CRect rcArea( m_ActiveRect );
if( rcArea.right <= rcArea.left
|| rcArea.bottom <= rcArea.top
)
return;
if( (! IsVisible() )
|| (GetStyle() & TBBS_HIDDEN) != 0
|| (! dc.RectVisible(&m_ActiveRect) )
)
return;
bool bDockSiteCustomizeMode =
pBar->_IsDockSiteCustomizeMode();
bool bPushed =
( IsPressed() && (!bDockSiteCustomizeMode) )
? true : false;
bool bEnabled =
( IsDisabled() && (!bDockSiteCustomizeMode) )
? false : true;
bool bHover =
( IsHover() && (!bDockSiteCustomizeMode) )
? true : false;
if( (! bDockSiteCustomizeMode )
&& (! GetBar()->IsForceHoverWhenMenuTracking() )
)
{
if( CExtToolControlBar::g_bMenuTracking
|| CExtPopupMenuWnd::IsMenuTracking()
)
bHover = false;
else if( !bHover )
bHover = IsPressedTracking();
//if( bPushed && bHover && IsPressedTracking() )
//bHover = false;
} // if( ! bDockSiteCustomizeMode ...
bool bIndeterminate =
( IsIndeterminate() && (!bDockSiteCustomizeMode) )
? true : false;
CExtSafeString sText = GetText();
CExtCmdIcon * pIcon = GetIconPtr();
CExtCmdIcon * pIconLarge = NULL;
if( pIcon != NULL
&& (! pIcon->IsEmpty() )
&& IsLargeIcon()
)
{
CSize _sizeIcon = pIcon->GetSize();
_sizeIcon.cx *= 2;
_sizeIcon.cy *= 2;
pIconLarge = new CExtCmdIcon;
if( pIconLarge->CreateScaledCopy(
*pIcon,
_sizeIcon
)
)
pIcon = pIconLarge;
#ifdef _DEBUG
else
{
ASSERT( FALSE );
}
#endif // _DEBUG
}
bool bPaintAsDropDown = IsPaintDropDown();
bool bHorz = IsHorzBarOrientation();
HFONT hFont =
(HFONT) pBar
-> OnGetToolbarFont( ! bHorz, false )
-> GetSafeHandle();
CExtPaintManager::PAINTPUSHBUTTONDATA _ppbd(
this,
bHorz,
rcArea,
sText,
pIcon,
true,
bHover,
bPushed,
bIndeterminate,
bEnabled,
m_bDrawBorder,
false,
false,
0,
hFont,
bPaintAsDropDown,
0,
(!bEnabled) || ( bEnabled && (!bHover) && (!bPushed) )
);
_ppbd.m_rcBorderSizes = OnQueryBorderSizes( bHorz );
_ppbd.m_nIconAlignment = OnQueryAlignmentIcon( bHorz );
_ppbd.m_nTextAlignment = OnQueryAlignmentText( bHorz );
_ppbd.m_rcIconMargins = OnQueryMarginsIcon( bHorz );
_ppbd.m_rcTextMargins = OnQueryMarginsText( bHorz );
if( OnQueryMaxButtonWidth( bHorz ) >= 0 )
_ppbd.m_bWordBreak = true;
if( GetSeparatedDropDown() )
{
_ppbd.m_bSeparatedDropDown = true;
_ppbd.m_bHoverDropDown = m_bDropDownHT;
if( ( m_bDropDownHT /*|| CExtToolControlBar::g_bMenuTracking*/ )
&& bPushed
&& ( ! bDockSiteCustomizeMode )
)
{
//_ppbd.m_bPushed = false;
_ppbd.m_bPushedDropDown = true;
}
}
_ppbd.m_clrCustomAccentEffectForIcon =
OnQueryCustomAccentEffectForIcon( dc );
bool bChecked =
( (GetStyle()&TBBS_CHECKED) != 0 )
? true
: false;
_ppbd.m_bChecked = bChecked;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// TO-DO: specify your desired text colors here
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
_ppbd.m_clrForceTextNormal = RGB(255,0,0);
_ppbd.m_clrForceTextHover = RGB(255,0,0);
_ppbd.m_clrForceTextPressed = RGB(255,0,0);
_ppbd.m_clrForceTextDisabled = RGB(255,0,0);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pBar->PmBridge_GetPM()->PaintPushButton( dc, _ppbd );
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
CExtCustomizeSite * pSite = pBar->GetCustomizeSite();
if( pSite != NULL
&& pSite->IsCustomizeMode()
&& pSite->CustomizedNodeGet() != NULL
&& pSite->CustomizedNodeGet() == GetCmdNode( false )
)
{
pBar->PmBridge_GetPM()->PaintDragSourceRect(
dc,
rcArea
);
}
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
if( pIconLarge != NULL )
delete pIconLarge;
if( bPaintChildren )
PaintChildren( dc, bPaintOneNearestChildrenLevelOnly );
}
};
And here is how your menu bar class should look like: class CYourMenuBar : public CExtMenuControlBar
{
public:
CYourMenuBar()
{
}
virtual ~CYourMenuBar()
{
}
CExtBarButton * OnCreateBarCommandBtn( UINT nCmdID, UINT nStyle = 0 )
{
ASSERT_VALID( this );
CExtBarButton * pTBB = new CYourMenuBarButton( this, nCmdID, nStyle );
ASSERT_VALID( pTBB );
return pTBB;
}
};
|
|
Joachim Meißner
|
Nov 1, 2009 - 11:40 AM
|
In CExtTreeCtrl WM_LBUTTONUP is not catched correctly. If I overwrite OnTreeMouseClick and supress the handling of WM_LBUTTONDOWN in my function like this: if (nMouseButton==VK_LBUTTON && nClick==0) {
return true;
}
then OnTreeMouseClick with nMouseButton==VK_LBUTTON && nClick==1 is called everytime, I release the LBUTTON. Otherwise, OnTreeMouseClick is called only after a double click. In CExtTreeCtrl::OnTreeMouseClick while handling WM_LBUTTONDOWN, SendMessage( WM_CANCELMODE ) is called. I suppose, this is the reason, why WM_LBUTTONUP ist not catched. Please provide a fix.
|
|
Technical Support
|
Nov 2, 2009 - 9:08 AM
|
Please provide us with more details about your task. Windows sends a WM_LBUTTON*** message to each window independently of the algorithms implemented in message handler methods. If your code eats up the WM_LBUTTONDOWN message, then this does not mean you should not receive the WM_LBUTTONUP message.
|
|
Joachim Meißner
|
Nov 18, 2009 - 4:21 AM
|
The Problem seems to be solved in 2.87.
|
|