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 » CExtListCtrl flickering black line when resizing column header, in unicode builds only Collapse All
Subject Author Date
M. Gamal Mar 10, 2010 - 2:42 AM

Hello,


When resizing a CExtListCtrl’s column header in a static unicode debug (and release) builds of any Prof-UIS sample that has a CExtListCtrl  (e.g. ProfUIS_Controls) I get a black flickering line along the left border of the column being resized. This doesn’t happen in the static MBCS builds.


In addition resizing column headers is noticeably slower in the unicode builds (kind of sluggish) than it is in the MBCS builds.


Both cases above are true when I define __EXT_MFC_ENABLE_TEMPLATED_CHARS and __EXT_MFC_COMPILED_WITH_NATIVE_WCHAR_T in the Prof-UIS library and the sample.


Any thoughts on what may be the cause of this?


Thanks.

Technical Support Mar 10, 2010 - 2:11 PM

First of all, template class based strings and characters is a unique feature of Prof-UIS which uses the latest C++ tricks like partial template specialization. We developed this feature to allow usage of different <b>native w_char_t support</code> options in Prof-UIS and Prof-UIS based projects. This feature is needed when you have more than one Prof-UIS based projects which use different <b>native w_char_t support</code> options due some reasons and you want to provide only one Prof-UIS DLL module with several Prof-UIS based EXE modules in scope of one your product installation. The template based character and string support is absolutely unreasonable and unneeded feature in static Prof-UIS library. We strongly recommend you to use the same <b>native w_char_t support</code> option both in Prof-UIS static library and in your projects based on Prof-UIS static library.

M. Gamal Mar 11, 2010 - 12:04 AM

Perhaps I didn’t explain myself very clearly, excuse me..


This issue happens even with the ’out of the box’ build settings for static unicode builds of Prof-UIS, i.e. When I let the wizard build the libraries for me. And when I build the libraries and samples myself without changing any settings of any kind or make any changes to code whatsoever.


I tried defining: __EXT_MFC_ENABLE_TEMPLATED_CHARS and __EXT_MFC_COMPILED_WITH_NATIVE_WCHAR_T  and it made no difference. And of course I use the same settings in the library and the Prof-UIS sample or my project!


Prof-UIS precompiled samples are a dynamic MBCS build, could you please try it with a static Unicode build. Thank you.

Technical Support Mar 12, 2010 - 1:24 AM

You reported the issue which is specific to the Unicode version of the Windows Common controls library because it can be reproduced only with a Unicode Prof-UIS version and using any Visual C++ version. This issue is related to the HDN_TRACK and HDN_ENDTRACK notifications handling code inside the list view common control. To fix it, please update the source code for the following methods:

void CExtHeaderCtrl::OnMouseMove( UINT nFlags, CPoint point )
{
            ASSERT_VALID( this );
//          CHeaderCtrl::OnMouseMove( nFlags, point );
            nFlags;
            if( m_nPressingColNo >= 0 )
            {
                        CExtPopupMenuTipWnd * pATTW = OnAdvancedPopupMenuTipWndGet();
                        if( pATTW != NULL )
                                    pATTW->Hide();
                        if( m_bOnDividerAtRight )
                        {
                                    CPoint ptScreenPressing = point;
                                    ClientToScreen( &ptScreenPressing );
                                    INT nExtent = ptScreenPressing.x - m_ptScreenPressing.x + m_nHelperInitialResizingExtent;
                                    HeaderItemExtentSet( m_nPressingColNo, nExtent );
                                    _DoSetCursor();
                                    if( m_bOnDividerAtRight )
                                    {
                                                HWND hWndParent = ::GetParent( m_hWnd );
                                                if( hWndParent != NULL )
                                                {
                                                            UINT nOwnID = UINT( GetDlgCtrlID() );
                                                            HD_NOTIFY _data, _data2;
                                                            ::memset( &_data, 0, sizeof(HD_NOTIFY) );
                                                            ::memset( &_data2, 0, sizeof(HD_NOTIFY) );
                                                            _data.hdr.hwndFrom = m_hWnd;
                                                            _data.hdr.idFrom = nOwnID;
                                                            _data.iButton = 0;
                                                            _data.iItem = m_nPressingColNo; // nColNo;
                                                            _data.hdr.code = HDN_TRACK;
HDITEM hdItemBuffer; // to avoid common controls crashing
::memset( &hdItemBuffer, 0, sizeof(HDITEM) );
hdItemBuffer.mask = HDI_WIDTH;
hdItemBuffer.cxy = nExtent;
_data.pitem = &hdItemBuffer;
                                                            ::memcpy( &_data2, &_data, sizeof(HD_NOTIFY) );
#if (defined _UNICODE)
                                                            ::LockWindowUpdate( hWndParent );
#endif // (defined _UNICODE)
                                                            ::SendMessage( hWndParent, WM_NOTIFY, WPARAM(nOwnID), LPARAM(&_data) );
#if (defined _UNICODE)
                                                            ::LockWindowUpdate( NULL );
#endif // (defined _UNICODE)
                                                            _data2.hdr.code = HDN_ITEMCHANGED;
                                                            ::SendMessage( hWndParent, WM_NOTIFY, WPARAM(nOwnID), LPARAM(&_data2) );
                                                            if( ::IsWindow( hWndParent ) && ::IsWindowVisible( hWndParent ) )
                                                                        ::InvalidateRect( hWndParent, NULL, TRUE );
                                                } // if( hWndParent != NULL )
                                    } // if( m_bOnDividerAtRight )
                                    return;
                        }
                        else if( ! m_bOnButton )
                        {
                                    if( _DndIsAllowed( m_nPressingColNo ) )
                                    {
                                                CPoint ptOffset = _DndGetStartOffset();
                                                CPoint ptClientPressing;
                                                ptClientPressing = m_ptScreenPressing;
                                                ScreenToClient( &ptClientPressing );
                                                CPoint ptDiff = ptClientPressing - point;
                                                if( abs(ptDiff.x) >= ptOffset.x || abs(ptDiff.y) >= ptOffset.y )
                                                {
                                                            _DndDo( m_nPressingColNo, m_ptScreenPressing );
                                                            return;
                                                }
                                    }
                        }
            }
bool bOnButton = false, bOnDividerAtRight = false;
INT nColNo = -1;
            if( CExtPopupMenuWnd::TestHoverEnabledFromActiveHWND( m_hWnd ) )
            {
                        CPoint ptScreen;
                        ptScreen = point;
                        ClientToScreen( &ptScreen );
                        if( ::WindowFromPoint( ptScreen ) == m_hWnd )
                                    nColNo = HitTestHeaderItem( point, &bOnButton, &bOnDividerAtRight );
            }
bool bHoverChanged = false;
            if(                     m_nHoverColNo != nColNo
                        ||           m_bOnButton != bOnButton
                        ||           ( m_bOnDividerAtRight != bOnDividerAtRight && ( ! CExtPopupMenuWnd::IsKeyPressed( VK_LBUTTON ) ) )
                        )
            {
                        bHoverChanged = true;
                        m_nHoverColNo = nColNo;
                        m_nHoverIndex = ColNo2VisualIndex( m_nHoverColNo );
                        m_bOnButton = bOnButton;
                        m_bOnDividerAtRight = bOnDividerAtRight;
                        if( m_bOnDividerAtRight )
                        {
                                    HWND hWndParent = ::GetParent( m_hWnd );
                                    if( hWndParent != NULL )
                                    {
                                                UINT nOwnID = UINT( GetDlgCtrlID() );
                                                HD_NOTIFY _data;
                                                ::memset( &_data, 0, sizeof(HD_NOTIFY) );
                                                _data.hdr.hwndFrom = m_hWnd;
                                                _data.hdr.idFrom = nOwnID;
                                                _data.iButton = 0;
                                                _data.iItem = nColNo;
                                                _data.hdr.code = HDN_BEGINTRACK;
HDITEM hdItemBuffer; // to avoid common controls crashing
::memset( &hdItemBuffer, 0, sizeof(HDITEM) );
_data.pitem = &hdItemBuffer;
                                                ::SendMessage( hWndParent, WM_NOTIFY, WPARAM(nOwnID), LPARAM(&_data) );
                                    } // if( hWndParent != NULL )
                        } // if( m_bOnDividerAtRight )
            }
            if( bHoverChanged )
            {
                        if( m_nPressingColNo < 0 )
                        {
                                    HWND hWndCapture = ::GetCapture();
                                    if( m_nHoverColNo >= 0 )
                                    {
                                                if( m_hWnd != hWndCapture )
                                                            SetCapture();
                                                if(                     m_nAdvancedTipStyle != INT(CExtPopupMenuTipWnd::__ETS_NONE)
                                                            &&        (! CExtPopupMenuWnd::IsMenuTracking() )
                                                            )
                                                {
                                                            CExtPopupMenuTipWnd * pATTW = OnAdvancedPopupMenuTipWndGet();
                                                            if( pATTW != NULL )
                                                            {
                                                                        const CExtHeaderCtrl::EXTENDED_ITEM_DATA & _eii = ExtendedItemDataGet( m_nHoverColNo );
                                                                        CRect rcArea;
                                                                        if( GetItemRect( m_nHoverColNo, rcArea ) )
                                                                        {
                                                                                    CRect _rcItem, _rcIcon, _rcText, _rcSortArrow, _rcButton, _rcButtonIcon;
                                                                                    bool bSorted = false,  bSortedAscending = false;
                                                                                    OnCalcHeaderItemLayout(
                                                                                                m_nHoverColNo,
                                                                                                rcArea,
                                                                                                _rcItem,
                                                                                                _rcIcon,
                                                                                                _rcText,
                                                                                                _rcSortArrow,
                                                                                                _rcButton,
                                                                                                _rcButtonIcon,
                                                                                                &bSorted,
                                                                                                &bSortedAscending
                                                                                                );
                                                                                    if( m_bOnButton )
                                                                                    {
                                                                                                rcArea.left = _rcButton.left;
                                                                                                rcArea.right = _rcButton.right;
                                                                                    }
                                                                                    else
                                                                                    {
                                                                                                rcArea.left = _rcItem.left;
                                                                                                rcArea.right = _rcItem.right;
                                                                                    }
                                                                                    ClientToScreen( &rcArea );
                                                                                    OnAdvancedPopupMenuTipWndDisplay(
                                                                                                *pATTW,
                                                                                                rcArea,
                                                                                                m_bOnButton ? LPCTSTR(_eii.m_strTipTextButton) : LPCTSTR(_eii.m_strTipTextItem)
                                                                                                );
                                                                        }
                                                            } // if( pATTW != NULL )
                                                }
                                    }
                                    else
                                    {
                                                if( m_hWnd == hWndCapture )
                                                            ReleaseCapture();
                                    }
                        } // if( m_nPressingColNo < 0 )
                        Invalidate();
                        _DoSetCursor();
            } // if( bHoverChanged )
}

void CExtHeaderCtrl::_CancelActions()
{
            ASSERT_VALID( this );
            if( m_bCancelingActions )
                        return;
            m_bCancelingActions = true;
            if( m_bOnDividerAtRight )
            {
                        HWND hWndParent = ::GetParent( m_hWnd );
                        if( hWndParent != NULL )
                        {
                                    UINT nOwnID = UINT( GetDlgCtrlID() );
                                    HD_NOTIFY _data, _data2;
                                    ::memset( &_data, 0, sizeof(HD_NOTIFY) );
                                    ::memset( &_data2, 0, sizeof(HD_NOTIFY) );
                                    _data.hdr.hwndFrom = m_hWnd;
                                    _data.hdr.idFrom = nOwnID;
                                    _data.iButton = 0;
                                    _data.iItem = m_nPressingColNo; //nColNo;
                                    _data.hdr.code = HDN_ENDTRACK;
HDITEM hdItemBuffer; // to avoid common controls crashing
::memset( &hdItemBuffer, 0, sizeof(HDITEM) );
_data.pitem = &hdItemBuffer;
                                    ::memcpy( &_data2, &_data, sizeof(HD_NOTIFY) );
#if (defined _UNICODE)
                                    ::LockWindowUpdate( hWndParent );
#endif // (defined _UNICODE)
                                    ::SendMessage( hWndParent, WM_NOTIFY, WPARAM(nOwnID), LPARAM(&_data) );
#if (defined _UNICODE)
                                    ::LockWindowUpdate( NULL );
#endif // (defined _UNICODE)
                                    _data2.hdr.code = HDN_ITEMCHANGED;
                                    ::SendMessage( hWndParent, WM_NOTIFY, WPARAM(nOwnID), LPARAM(&_data2) );
                                    if( ::IsWindow( hWndParent ) && ::IsWindowVisible( hWndParent ) )
                                                ::InvalidateRect( hWndParent, NULL, TRUE );
                        } // if( hWndParent != NULL )
            } // if( m_bOnDividerAtRight )
            if(                     ( m_nHoverColNo >= 0 || m_nPressingColNo >= 0 )
                        &&        GetSafeHwnd() != NULL
                        )
                        Invalidate();
            m_ptScreenPressing.x = m_ptScreenPressing.y = m_nHelperInitialResizingExtent = -32767;
            m_nHoverColNo = m_nHoverIndex = m_nPressingColNo = m_nPressingIndex = -1;
            m_bOnButton = m_bOnDividerAtRight = false;
            if( ::GetCapture() == m_hWnd )
                        ReleaseCapture();
            m_bCancelingActions = false;
}

M. Gamal Mar 10, 2010 - 2:46 AM

continued: this is most visible in the first column of the list control. I am using Visual Studio 2008.