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 » CExtSpinWnd and SetBuddy == broken Collapse All
Subject Author Date
Jeroen Walter Mar 18, 2010 - 6:43 AM

using profuis 2.87


CExtSpinWnd only draws correctly of the autobuddy style is set.


The method CExtSpinWnd::_IsBuddyToEdit does not take into account that I may have set the buddy via the SetBuddy() method.


Please fix this.


 


 

Jeroen Walter Mar 24, 2010 - 9:49 AM

Thanks,


However the way you use GetClassName is errorprone, as GetClassName truncates the returned class name.


For example, if I have a registered window class name "EditableCombobox" then this method will think my combobox is an edit box and _IsBuddyToEdit() will still return true.....


Also, I think you can skip the check on UDS_AUTOBUDDY, as UDM_GETBUDDY will return the buddy also if you have the autobuddy style.


 

Technical Support Mar 25, 2010 - 2:42 AM

We replaced the following line of code:

TCHAR szCompare[ sizeof(szEdit)/sizeof(szEdit[0]) + 1 ];

With the following one:
TCHAR szCompare[ 512 ];
We agree you have the right to implement your own editable windows. Here is the entire method’s source code:
bool CExtSpinWnd::_IsBuddyToEdit()
{
            ASSERT_VALID( this );
            if( GetSafeHwnd() == NULL )
                        return false;
DWORD dwStyle = GetStyle();
bool bSpinAlignRight = ( ( dwStyle & UDS_ALIGNRIGHT ) != 0 ) ? true : false;
bool bSpinAlignLeft = ( ( dwStyle & UDS_ALIGNLEFT ) != 0 ) ? true : false;
            if( ! ( bSpinAlignRight || bSpinAlignLeft ) )
                        return false;
HWND hWndBuddyTest = NULL;
static const TCHAR szEdit[] = _T("EDIT");
TCHAR szCompare[ 512 ];
            if( ( dwStyle & UDS_AUTOBUDDY ) != 0 )
            {
                        hWndBuddyTest = ::GetWindow( m_hWnd, GW_HWNDPREV );
                        if( hWndBuddyTest != NULL )
                        {
                                    ::memset( szCompare, 0, sizeof(szCompare) );
                                    ::GetClassName( hWndBuddyTest, szCompare, sizeof(szCompare)/sizeof(szCompare[0]) );
                                    if( ::lstrcmpi( szCompare, szEdit ) != 0 )
                                                hWndBuddyTest = NULL;
                        }
            }
            if( hWndBuddyTest == NULL )
            {
                        hWndBuddyTest = (HWND) SendMessage( UDM_GETBUDDY, 0L, 0L );
                        if( hWndBuddyTest != NULL && ::IsWindow( hWndBuddyTest ) )
                        {
                                    ::memset( szCompare, 0, sizeof(szCompare) );
                                    ::GetClassName( hWndBuddyTest, szCompare, sizeof(szCompare)/sizeof(szCompare[0]) );
                                    if( ::lstrcmpi( szCompare, szEdit ) != 0 )
                                                hWndBuddyTest = NULL;
                        }
                        else
                                    hWndBuddyTest = NULL;
            }
            return ( hWndBuddyTest != NULL ) ? true : false;
}
But we would prefer to leave the UDS_AUTOBUDDY style checking code to be exactly 100% sure about the CExtSpinWnd is backward compatible with all the customer projects.

Jeroen Walter Mar 25, 2010 - 2:56 AM

Thanks.


Just for my understanding, is it the intention of the CExtSpinWnd to only be a buddy to an edit box?


I’m asking this because it is possible (though arguably useless) to buddy a spincontrol to other types of controls as well.


In the resource editor of Visual Studio you can test this, just create a checkbox or combobox and create a spincontrol with the autobuddy and set buddy int styles.


If your CExtSpinWnd is meant to be a drop-in replacement of CSpinButtonCtrl, then you should not limit the buddying to edit boxes only.

Technical Support Mar 25, 2010 - 7:52 AM

Here is a screenshot demonstrating several auto buddy spin controls attached to several different common controls.

http://www.prof-uis.com/download/forums/tmp/AutoBuddySpinCtrl.png

In the real world, only the simple edit common control supports the best integration with the spin common control.

Jeroen Walter Mar 26, 2010 - 4:09 AM

Still, it’s possible


Not that I need it, I was just wondering (not criticizing) in how far the ProfUis controls are supposed to be a drop-in replacement for the default MFC controls, i.e. maintaining the same functionality.


 

Technical Support Mar 26, 2010 - 11:14 AM

Each control is specific. The CExtEdit class supports a themed border, Prof-UIS context menu and several additional handy methods like changing text/background colors. The CExtButton class supports an icon, a split button mode and a built in-menu. The CExtColorButton class is a CExtButton-based button which displays a color picker popup menu and automatically generates a color icon. The CExtCheckBox and CExtRadioButton and just skinned versions of appropriate common controls. The CExtGroupBox is also just a skinned control, but it supports several optional skinning modes. The CExtListCtrl class supports an improved and themed header control and sorting. The CExtTreeCtrl class is very improved and completely re-painted tree view common control. If you need the classic tree view common control but with Prof-UIS themed scroll bars, then you can simply use the CExtNCSB < CTreeCtrl > template based class type. The CExtThemedTabCtrl is just a themed tab common control which Prof-UIS uses only in themed property sheet windows. The CExtTabWnd class is a tab window written from scratch and Prof-UIS uses everywhere we need the tabs. The CExtMenuControlBar, CExtPanelControlBar, CExtControlBar, CExtRibbonBar bars are bars written from scratch. The grids, of course, also written from scratch. The most complex and big parts of Prof-UIS are not related to Window common controls.

Technical Support Mar 20, 2010 - 11:25 AM

Thank you for reporting this issue. To fix it, please update the source code for the following method:

bool CExtSpinWnd::_IsBuddyToEdit()
{
            ASSERT_VALID( this );
            if( GetSafeHwnd() == NULL )
                        return false;
DWORD dwStyle = GetStyle();
bool bSpinAlignRight = ( ( dwStyle & UDS_ALIGNRIGHT ) != 0 ) ? true : false;
bool bSpinAlignLeft = ( ( dwStyle & UDS_ALIGNLEFT ) != 0 ) ? true : false;
            if( ! ( bSpinAlignRight || bSpinAlignLeft ) )
                        return false;
HWND hWndBuddyTest = NULL;
static const TCHAR szEdit[] = _T("EDIT");
TCHAR szCompare[ sizeof(szEdit)/sizeof(szEdit[0]) + 1 ];
            if( ( dwStyle & UDS_AUTOBUDDY ) != 0 )
            {
                        hWndBuddyTest = ::GetWindow( m_hWnd, GW_HWNDPREV );
                        if( hWndBuddyTest != NULL )
                        {
                                    ::memset( szCompare, 0, sizeof(szCompare) );
                                    ::GetClassName( hWndBuddyTest, szCompare, sizeof(szCompare)/sizeof(szCompare[0]) );
                                    if( ::lstrcmpi( szCompare, szEdit ) != 0 )
                                                hWndBuddyTest = NULL;
                        }
            }
            if( hWndBuddyTest == NULL )
            {
                        hWndBuddyTest = (HWND) SendMessage( UDM_GETBUDDY, 0L, 0L );
                        if( hWndBuddyTest != NULL && ::IsWindow( hWndBuddyTest ) )
                        {
                                    ::memset( szCompare, 0, sizeof(szCompare) );
                                    ::GetClassName( hWndBuddyTest, szCompare, sizeof(szCompare)/sizeof(szCompare[0]) );
                                    if( ::lstrcmpi( szCompare, szEdit ) != 0 )
                                                hWndBuddyTest = NULL;
                        }
                        else
                                    hWndBuddyTest = NULL;
            }
            return ( hWndBuddyTest != NULL ) ? true : false;
}