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 » Using the in place editor in a CExtGridCellCheckListComboBox cell (possible bug?) Collapse All
Subject Author Date
Christophe Guibert Oct 14, 2007 - 3:31 PM

Dear Support,

I use a CExtGridCellCheckListComboBox derived class in a grid to allow multiple selection.

In your ProfUIS_Controls sample, Grid tab, CheckComboBox column (6th) , I would like to type new values (separated by ; delimitor) and add them to the current list of values, but the editable field is emptied when I leave it and none of the new values are added to the list.

Worse, in the first row, I select two items (for instance Windows 98 and Windows 2000), they are displayed as "Windows 98; Windows 2000" in the cell. Then I click to activate the in-place editor and set the insertion point anywhere in the string, BUT DO NOT TYPE ANYTHING : just a click. When leaving the in-place editor, only "Windows 2000", the last value, is kept. (possible bug ?).

I used a derived class where the OnInplaceControlTextInputComplete() method was overriden and added a piece of code to extract the values between the delimitors in the new text, add them to the Cell and Check them :

	if(		bSaveChanges
		&&	_tcscmp( LPCTSTR(sText), LPCTSTR(sTextNew) ) != 0  
		)
	{
		CStringList list;
		CString separator = _T(";");
		CString str(sTextNew);
		::ExplodeWords(str, &list, separator, TRUE);  // parsing the new text
		for (POSITION pos = list.GetHeadPosition(); pos != NULL ; )
		{
			CString val = list.GetNext(pos);
			int index = FindStringExact(val);
			if (index < 0)
			{
				// new value : add it
				int idx = AddString(val);
				ItemCheckSet(idx, 1);
			}
			else
			{
				ItemCheckSet(index, 1);
			}
		}
		list.RemoveAll();
		TextSet(sTextNew);
...


It almost works :
- the new values that were typed in the in-place editor are added (they weren’t before),
- but only the last one is checked (although all calls to ItemCheckSet returned 1),
- the Cell displays only the last one (like in the ProfUIS_Controls sample).

Could you say if I miss something, if there’s a bug, or both ?

Best Regards,

Christophe Guibert

Technical Support Oct 16, 2007 - 5:29 AM

We completely agree with you. Thank you. In the bug fix the following line

strWalk1 += ( nLenSep * sizeof(TCHAR) );
in fact should be
strWalk1 += nLenSep;


Technical Support Oct 15, 2007 - 1:10 PM

Thank you for reporting this bug. Below is the bug fix.

void CExtGridCellCheckListComboBox::TextSet(
	__EXT_MFC_SAFE_LPCTSTR str, // = __EXT_MFC_SAFE_LPCTSTR(NULL) // empty text
	bool bAllowChangeDataType // = false
	)
{
	ASSERT_VALID( this );
	bAllowChangeDataType;

	ItemCheckAll( 0 );
	
CExtSafeString strListSeparator;
	OnQueryListSeparator( strListSeparator );
INT nLenSep = INT(_tcslen(strListSeparator));

LPCTSTR strWalk = str;
LPCTSTR strWalk1 = NULL;
	while( true )
	{
		strWalk1 = _tcsstr( strWalk, strListSeparator );
		
		LONG nBufferLen = 0L;
		if( strWalk1 != NULL )
			nBufferLen = ( LONG(strWalk1) - LONG(strWalk) ) / sizeof(TCHAR);
		else
			nBufferLen = INT( _tcslen( strWalk ) );
		
		ASSERT( nBufferLen >= 0 );

		LONG nBufferSize = ( nBufferLen + 1 ) * sizeof(TCHAR);

		TCHAR * lpstrBuffer = new TCHAR[ nBufferSize ];
		ASSERT( lpstrBuffer != NULL );
		::memset( lpstrBuffer, 0, nBufferSize );
		__EXT_MFC_STRNCPY( lpstrBuffer, nBufferLen + 1, strWalk, nBufferLen );

		CExtSafeString sBuffer( lpstrBuffer );
		sBuffer.TrimLeft( _T(" ") );
		sBuffer.TrimRight( _T(" ") );
		
		LONG nItem = FindStringExact( sBuffer );
		if( nItem >= 0L )
			ItemCheckSet( nItem, 1 );

		delete [] lpstrBuffer;
		lpstrBuffer = NULL;
		
		if( strWalk1 == NULL )
			break;

		strWalk1 += ( nLenSep * sizeof(TCHAR) );
		strWalk = strWalk1;
	}
}

Christophe Guibert Oct 15, 2007 - 3:22 PM

I thank you for the prompt response, which makes the sample work properly, and my application better, but not completely : some characters are lost in Unicode build.

I suppose that the

strWalk1 += ( nLenSep * sizeof(TCHAR) );
should be replaced by
strWalk1 += nLenSep;

as it was before, because the += operator should deal with Unicode char width.

I propose the code below, which finally works and adds items in the list if the user types new ones with delimitors. Of course, it should be adapted to wider situations, but this is what I needed and is consistent wih editable combo boxes.
void CMyDerivedCheckListComboCell::TextSet(
		__EXT_MFC_SAFE_LPCTSTR str, // = __EXT_MFC_SAFE_LPCTSTR(NULL) // empty text    
		bool bAllowChangeDataType // = false    
		)
{    
	ASSERT_VALID( this );    
	bAllowChangeDataType;    
	ItemCheckAll( 0 );    
	CExtSafeString strListSeparator;    
	OnQueryListSeparator( strListSeparator );
	INT nLenSep = INT(_tcslen(strListSeparator));
	LPCTSTR strWalk = str;
	LPCTSTR strWalk1 = NULL;    
	while( true )    
	{        
		strWalk1 = _tcsstr( strWalk, strListSeparator );                
		LONG nBufferLen = 0L;        
		if( strWalk1 != NULL )            
			nBufferLen = ( LONG(strWalk1) - LONG(strWalk) ) / sizeof(TCHAR);        
		else            
			nBufferLen = INT( _tcslen( strWalk ) ); 
		
		ASSERT( nBufferLen >= 0 );        
		LONG nBufferSize = ( nBufferLen + 1 ) * sizeof(TCHAR);        
		TCHAR * lpstrBuffer = new TCHAR[ nBufferSize ];        
		ASSERT( lpstrBuffer != NULL );        
		::memset( lpstrBuffer, 0, nBufferSize );        
		__EXT_MFC_STRNCPY( lpstrBuffer, nBufferLen + 1, strWalk, nBufferLen );     
		
		CExtSafeString sBuffer( lpstrBuffer );        
		sBuffer.TrimLeft( _T(" ") );        
		sBuffer.TrimRight( _T(" ") );  
		
		LONG nItem = FindStringExact( sBuffer );        
		if( nItem >= 0L )            
			ItemCheckSet( nItem, 1 );
		// Modification - chr
		else
		{
			// new item : add it
			if (sBuffer != _T(""))
			{
				LONG nNew = AddString( sBuffer );
				if( nNew >= 0L )            
					ItemCheckSet( nNew, 1 );	
			}
		}
		// End of modification - chr
		
		delete [] lpstrBuffer;        
		lpstrBuffer = NULL;     
		
		if( strWalk1 == NULL )            
			break; 
		
		strWalk1 += ( nLenSep ); //* sizeof(TCHAR) );        
		strWalk = strWalk1;    
	}
}


Best Regards,

Christophe Guibert

Technical Support Oct 15, 2007 - 8:37 AM

Unfortunately we cannot reproduce the problem with showing only the last checked item in the cell. Would you create and send us some test project (or change the Prof-UIS_Controls sample) in a way that demonstrates the problem?

Christophe Guibert Oct 15, 2007 - 11:31 AM

I discovered that the Prof-UIS_Controls sample behaves properly in MBCS version, but NOT in Unicode version. So what I described earlier still applies to this version.

So you could try with Unicode : I suspect your parsing code for delimited text in the CExtGridCellCheckListComboBox implementation.

Hoping it will help,

Best Regards,

Christophe Guibert