Professional UI Solutions
Site Map   /  Register


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 » CExtScrollBar and SB_XXX messages Collapse All
Subject Author Date
Jeroen Walter May 17, 2010 - 6:59 AM

Using profuis 2.87.


We want to use the CExtNCSB template for skinning the scrollbars of some of our custom controls. These controls use the SB_LINE and SB_PAGE codes of the scrollbar’s WM_VSCROLL message.

We noticed these codes no longer are sent by the scrollbar while using CExtNCSB.

According to the profuis documentation "The CExtScrollBar class extends the functionality of the MFC’s CScrollBar class".

Unfortunately this is not the case. It breaks the CScrollBar functionality, because in your infinite wisdom you have decided to no longer send the SB_LINE and SB_PAGE messages, but instead only send the SB_THUMB messages.

Somewhere in this forum you have justified this by saying that it is handy as you then always have the current scrollposition. It’s NOT!

The whole point of the SB_LINE and SB_PAGE messages is to allow the parent control to decide what to do with the scrollposition.

By only sending the SB_THUMB messages you break the default behaviour of the CScrollBar, making the CExtScrollBar useless as a replacement for CScrollBar in existing applications that just want the skinning capabilities of ProfUis.

As you also use the CExtScrollBar for the CExtNCSB template, this template is also quite useless.

Could you please fix CExtScrollBar and CExtNCSB  so that it behaves just like the CScrollBar or create another class that has that behaviour?



Technical Support May 18, 2010 - 11:50 AM

We always use the SetScrollInfo() Win32 API first. If it returns an error, then we use very old style 16-bit APIs. This provides compatibility with old Windows versions.

Jeroen Walter May 19, 2010 - 1:36 AM

The point I was trying to make is that SetScrollInfo does not update the trackposition.

Therefore calling SetScrollInfo during the handling of a SB_THUMBTRACK notification is rather pointless.

Code that relies on the scrollinfo to be correct during their own handling of SB_THUMBTRACK then will no longer function correctly without modification.

This makes the use of CExtNSCB as a drop-in replacement for skinned scrollbars rather difficult.

Technical Support May 18, 2010 - 11:49 AM

This is not a bug. The SetScrollInfo() Win32 API does not cause any messages to be sent and we simply cannot get notified when your code invokes it. Please invoke the NCSB_RescanContainers() API in your CExtNCSB-based class method which invokes the SetScrollInfo() Win32 API.

Jeroen Walter May 19, 2010 - 1:37 AM

I’m sorry to here this. I was hoping CExtNSCB could intercept the SetScrollInfo somehow and update itself accordingly.


Technical Support May 20, 2010 - 1:38 PM

Very unfortunately, there is no such notification. The scrolling is even worst in the particular case. For example, we can find the scrollable window inside the Internet Explorer Active X control and this window understands the WM_HSCROLL / WM_VSCROLL messages, but the GetScrollInfo() Win32 API returns zero values. We cannot skin the scroll bars of the Internet Explorer Active X control without accessing its automation APIs for hacking its mystic scrolling implementation. The alternative (and not the best) solution is to run some 100-200 milliseconds period based timer which will invoke the GetScrollInfo() API for scanning the scrolling state changes.

Jeroen Walter May 21, 2010 - 1:09 AM

Well, I’m glad you gave it some thought anyway and I thank you for the solution you gave me.

But I still would like to know if this solution will be part of future ProfUis releases, because I don’t want to have to patch new releases.


Technical Support May 21, 2010 - 7:35 AM

Yes, it’s already part of Prof-UIS. You can drop us an e-mail to the support mail box at this web site and we will provide you with the latest Prof-UIS 2.90 download information.

Technical Support May 17, 2010 - 2:45 PM

The scroll bar action notifications are supported but we didn’t sent them because they are not working with most of the common controls. The CExtNCSB template class is the most often used with common controls. But it’s not a problem to provide the scroll bar’s action notifications by default and do not provide them for the automatically detected common controls. Please update the source code for the following method:

CExtScrollBar * CExtNCSB_ScrollContainer::OnInstantiateAndCreateScrollBar( bool bChildMode )
            ASSERT_VALID( this );
            if( GetSafeHwnd() == NULL )
                        return NULL;
e_mode_t eMode = GetMode();
            if( ! ( eMode == __EM_HORIZONTAL_SCROLL_BAR || eMode == __EM_VERTICAL_SCROLL_BAR ) )
                        return NULL;
CExtScrollBar * pWndScrollBar = NULL;
                        TCHAR szCompare[512] = _T("");
                        ::GetClassName( m_hWndScrollingTaget, szCompare, sizeof( szCompare ) / sizeof( szCompare[0] ) );
                        pWndScrollBar = new CExtScrollBar;
                        if(                     _tcsicmp(  szCompare, _T("edit") ) == 0
                                    ||           _tcsnicmp( szCompare, _T("riched"), 6 ) == 0
                                    ||           _tcsicmp(  szCompare, _T("listbox") ) == 0
                                    ||           _tcsicmp(  szCompare, _T("combolbox") ) == 0
                                    ||           _tcsicmp(  szCompare, _T("systreeview32") ) == 0
                                    ||           _tcsicmp(  szCompare, _T("syslistview32") ) == 0
                                    pWndScrollBar->m_bAlwaysSendThumbButtonNotifications = true;
                                    pWndScrollBar->m_bSendActionNotifications = false;
                        if( ! bChildMode )
                                    pWndScrollBar->m_bPopupInactiveLightMode = true;
                                    pWndScrollBar->m_bEnableHookSpy = true;
                                    pWndScrollBar->m_nMouseActivateCode = MA_NOACTIVATE;
                        CRect rc;
                        GetClientRect( &rc );
                        if( ! pWndScrollBar->Create(
                                                            | ( ( eMode == __EM_HORIZONTAL_SCROLL_BAR ) ? SBS_HORZ : SBS_VERT )
                                    return NULL;
                        return pWndScrollBar;
            catch( CException * pException )
            catch( ... )
            if( pWndScrollBar != NULL )
                        delete pWndScrollBar;
            return NULL;

Jeroen Walter May 18, 2010 - 4:03 AM


Thanks for the solution.

Will this solution also be present in future releases of ProfUis?

I’m always a bit wary to just implement proposed fixes in the Profuis source code, as I don’t know if these fixes also will be available in the next ProfUis version.

We are using a third-party control that relies on the correct function of the scrollbars and their notifications.

I now get the SB_LINE & SB_PAGE notifications, which is fine, but there is however another bug.

What we are seeing is that, when using CExtNCSB, the SCROLLINFO of the control has not been updated correctly when the SB_THUMBTRACK notification arrives.

To test this, we call GetScrollInfo(SB_VERT, &si, SIF_ALL) when the SB_THUMBTRACK notification arrives (via WM_VSCROLL), with si a SCROLLINFO.

We notice that the si.nTrackPos that is returned is NOT the trackpos as given by the position in the wParam argument of the WM_VSCROLL message generated by CExtNCSB.

Instead the trackpos is the same as the si.nPos.

This is different from the normal behavior of a scrollbar. The trackpos must be different from si.nPos, it must be the same as the wParam argument hiword.

I’ve digged somewhat in the CExtScrollBar and CExtNCSB code and found out that you synchronize the control’s scrollinfo with the CExtScrollBar in the ncsb scrollbar container and vice versa via a call to SetScrollInfo() (via NCSB_UpdateChannel) but only AFTER the WindowProc of control has handled the WM_VSCROLL message.

I tried to synchronize the control’s scrollinfo by calling NCSB_UpdateChannel in the WM_VSCROLL handler, but to no avail.

Unfortunately it is not possible to set the trackpos via SetScrollInfo (see the MSDN docs of the SetScrollInfo Function).

Maybe you can find another way of fixing this problem, because now if not, then this means that your solution with CExtNCSB does not work for all controls and may even not work for some of the common controls in all cases.


I also found what I think is a bug in CExtNCSB_Impl::NCSB_SetScrollInfoWindow().

One of the first lines of this method clears the scrollinfo structure that is passed as argument and that holds the information to be set via SetScrollInfo.

-->    ::memset( &_scroll_info, 0, sizeof(SCROLLINFO) );

This is not correct I think.


Technical Support May 18, 2010 - 11:50 AM

We agree about the bug in the NCSB_SetScrollInfoWindow() method. The ::memset( &_scroll_info, 0, sizeof(SCROLLINFO) ); line of code should be commented in it.

You can get the track position from the CExtScrollBar windows via invoking the NCSB_GetScrollInfoBar() method in your CExtNCSB-based class.

Jeroen Walter May 18, 2010 - 5:16 AM

I found another bug.


When I set the scrollposition from within the WM_VSCROLL handler while still pressing the down scrollbutton with the mouse, the CExtScrollbar is not updated to reflect the new position. It is only updated after I release the mouse button.

The CExtScrollBar should be synchronized after each call to the control’s SetScrollInfo() and related functions.



Jeroen Walter May 18, 2010 - 4:07 AM


GetScrollInfo(SB_VERT, &si, SIF_ALL) is used to get the 32-bit integer trackposition instead of the 16-bit version in the hiword of wParam.

Therefore it’s not an option to just use the 16-bit version.