Hi,
Here is the ready-to use source code for the password cell class. It is based on the CExtGridCellStringDM
class, but shows **** instead of password text. Please put the following code somewhere in the header file:
////////////////////////////////////
// CExtGridCellPassword
class CExtGridCellPassword
: public CExtGridCellStringDM
{
class CMyGridInplaceEdit : public CExtGridInplaceEdit
{
public:
CMyGridInplaceEdit(
CExtGridWnd & wndGrid,
CExtGridCell & cell,
LONG nVisibleColNo,
LONG nVisibleRowNo,
LONG nColNo,
LONG nRowNo,
INT nColType,
INT nRowType,
const RECT & rcCellExtra,
const RECT & rcCell,
const RECT & rcInplaceControl,
LONG nLastEditedColNo,
LONG nLastEditedRowNo
)
: CExtGridInplaceEdit(
wndGrid,
cell,
nVisibleColNo,
nVisibleRowNo,
nColNo,
nRowNo,
nColType,
nRowType,
rcCellExtra,
rcCell,
rcInplaceControl,
nLastEditedColNo,
nLastEditedRowNo
)
{
}
virtual bool Create()
{
ASSERT_VALID( this );
ASSERT( m_hWnd == NULL );
if( m_wndGrid.GetSafeHwnd() == NULL )
{
ASSERT( FALSE );
delete this;
return false;
}
DWORD dwAreaFlags =
CExtGridHitTestInfo::CellTypesToAreaFlags(
m_nColType,
m_nRowType
);
HFONT hFont =
m_cell.OnQueryCellFont(
m_wndGrid,
m_nVisibleColNo,
m_nVisibleRowNo,
m_nColNo,
m_nRowNo,
m_nColType,
m_nRowType,
dwAreaFlags
);
if( hFont == NULL )
{
hFont = (HFONT)
m_wndGrid.OnSiwGetDefaultFont().GetSafeHandle();
if( hFont == NULL )
hFont = (HFONT)
::GetStockObject(DEFAULT_GUI_FONT);
if( hFont == NULL )
{
if( hFont == NULL )
hFont = (HFONT)
::GetStockObject(SYSTEM_FONT);
if( hFont == NULL )
{
ASSERT( FALSE );
delete this;
return false;
}
}
}
LOGFONT lf;
VERIFY( ::GetObject(hFont,sizeof(LOGFONT),&lf) );
if( ! m_font.CreateFontIndirect(&lf) )
{
ASSERT( FALSE );
delete this;
return false;
}
CRect rcWnd( m_rcInplaceControl );
rcWnd.OffsetRect( 0, 1 );
UINT nDrawTextFlags =
m_cell.OnQueryDrawTextFlags(
m_nVisibleColNo,
m_nVisibleRowNo,
m_nColNo,
m_nRowNo,
m_nColType,
m_nRowType,
dwAreaFlags
);
DWORD dwStyle = WS_CHILD|ES_AUTOHSCROLL;
if( nDrawTextFlags & DT_RIGHT )
dwStyle |= ES_RIGHT;
if( nDrawTextFlags & DT_CENTER )
dwStyle |= ES_CENTER;
else
dwStyle |= ES_LEFT;
DWORD dwCellStyle = m_cell.GetStyle();
if( (dwCellStyle&__EGCS_READ_ONLY) != 0 )
dwStyle |= ES_READONLY;
m_bInConstruction = true;
HWND hWnd =
::CreateWindowEx(
0L,
_T("EDIT"),
_T(""),
dwStyle|ES_PASSWORD,
rcWnd.left,
rcWnd.top,
rcWnd.Width(),
rcWnd.Height(),
m_wndGrid.GetSafeHwnd(),
NULL,
::AfxGetInstanceHandle(),
0L
);
if( hWnd == NULL )
{
ASSERT( FALSE );
delete this;
return false;
}
if( ! SubclassWindow( hWnd ) )
{
ASSERT( FALSE );
ASSERT( CWnd::FromHandlePermanent(hWnd) == NULL );
::DestroyWindow( hWnd );
delete this;
return false;
}
m_cell.TextGet( m_strTextPrevious );
m_strTextInitial = m_strTextPrevious;
if( ! m_strTextInitial.IsEmpty() )
SetWindowText( LPCTSTR(m_strTextInitial) );
SetFont( &m_font );
SetMargins( 2, 0 );
if( m_nLastEditedRowNo == m_nRowNo )
{
if( m_nLastEditedColNo == (m_nColNo - 1L) )
SetSel( 0, 0 );
else if( m_nLastEditedColNo == (m_nColNo + 1L) )
SetSel( -1, -1 );
else
SetSel( 0, -1 );
} // if( m_nLastEditedRowNo == m_nRowNo )
else
SetSel( 0, -1 );
SetWindowPos(
&CWnd::wndTop,0,0,0,0,
SWP_NOMOVE|SWP_NOSIZE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_SHOWWINDOW
);
SetFocus();
m_bInConstruction = false;
return true;
}
}; // class CMyGridInplaceEdit
public:
DECLARE_DYNCREATE( CExtGridCellPassword );
IMPLEMENT_ExtGridCell_Clone(
CExtGridCellPassword, CExtGridCellStringDM );
CExtGridCellPassword(
CExtGridDataProvider * pDataProvider = NULL
);
CExtGridCellPassword( CExtGridCellPassword & other );
virtual HWND OnInplaceControlCreate(
CExtGridWnd & wndGrid,
LONG nVisibleColNo,
LONG nVisibleRowNo,
LONG nColNo,
LONG nRowNo,
INT nColType,
INT nRowType,
const RECT & rcCellExtra,
const RECT & rcCell,
const RECT & rcInplaceControl,
LONG nLastEditedColNo,
LONG nLastEditedRowNo
);
virtual void OnPaintText(
const RECT & rcCellText,
const CExtGridWnd & wndGrid,
CDC & dc,
LONG nVisibleColNo,
LONG nVisibleRowNo,
LONG nColNo,
LONG nRowNo,
INT nColType,
INT nRowType,
const RECT & rcCellExtra,
const RECT & rcCell,
const RECT & rcVisibleRange,
DWORD dwAreaFlags,
DWORD dwHelperPaintFlags
) const;
}; // class CExtGridCellPassword
Please put the following code somewhere in CPP file:
CExtGridCellPassword::CExtGridCellPassword(
CExtGridDataProvider * pDataProvider // = NULL
)
: CExtGridCellStringDM( pDataProvider )
{
}
CExtGridCellPassword::CExtGridCellPassword(
CExtGridCellPassword & other
)
: CExtGridCellStringDM( other )
{
}
HWND CExtGridCellPassword::OnInplaceControlCreate(
CExtGridWnd & wndGrid,
LONG nVisibleColNo,
LONG nVisibleRowNo,
LONG nColNo,
LONG nRowNo,
INT nColType,
INT nRowType,
const RECT & rcCellExtra,
const RECT & rcCell,
const RECT & rcInplaceControl,
LONG nLastEditedColNo,
LONG nLastEditedRowNo
)
{
ASSERT_VALID( this );
ASSERT_VALID( (&wndGrid) );
DWORD dwCellStyle = GetStyle();
if( (dwCellStyle&__EGCS_NO_INPLACE_CONTROL) != 0 )
return NULL;
CExtGridInplaceEdit * pEdit = NULL;
try
{
pEdit =
new CMyGridInplaceEdit(
wndGrid,
*this,
nVisibleColNo,
nVisibleRowNo,
nColNo,
nRowNo,
nColType,
nRowType,
rcCellExtra,
rcCell,
rcInplaceControl,
nLastEditedColNo,
nLastEditedRowNo
);
ASSERT_VALID( pEdit );
if( ! pEdit->Create() )
{
ASSERT( FALSE );
return NULL;
} // if( ! pEdit->Create() )
} // try
catch( CException * pXept )
{
ASSERT( FALSE );
pXept->Delete();
return NULL;
} // catch( CException * pXept )
catch( ... )
{
ASSERT( FALSE );
return NULL;
} // catch( ... )
ASSERT_VALID( pEdit );
HWND hWnd = pEdit->GetSafeHwnd();
ASSERT( hWnd != NULL && ::IsWindow(hWnd) );
return hWnd;
}
void CExtGridCellPassword::OnPaintText(
const RECT & rcCellText,
const CExtGridWnd & wndGrid,
CDC & dc,
LONG nVisibleColNo,
LONG nVisibleRowNo,
LONG nColNo,
LONG nRowNo,
INT nColType,
INT nRowType,
const RECT & rcCellExtra,
const RECT & rcCell,
const RECT & rcVisibleRange,
DWORD dwAreaFlags,
DWORD dwHelperPaintFlags
) const
{
ASSERT_VALID( this );
ASSERT_VALID( (&wndGrid) );
ASSERT( dc.GetSafeHdc() != NULL );
if( ! dc.RectVisible(&rcCellText) )
return;
rcCellExtra;
rcCell;
rcVisibleRange;
COLORREF clrTextOld = COLORREF(-1L);
HFONT hOldFont = NULL;
HFONT hCellFont =
OnQueryCellFont(
wndGrid,
nVisibleColNo,
nVisibleRowNo,
nColNo,
nRowNo,
nColType,
nRowType,
dwAreaFlags
);
if( hCellFont != NULL )
hOldFont = (HFONT)::SelectObject( dc, hCellFont );
if( rcCellText.left < rcCellText.right
&& rcCellText.top < rcCellText.bottom
)
{ // if text painting area is not empty
UINT nDrawTextFlags =
OnQueryDrawTextFlags(
nVisibleColNo,
nVisibleRowNo,
nColNo,
nRowNo,
nColType,
nRowType,
dwAreaFlags
);
LPCTSTR strTextBuffer = LPCTSTR( GetTextBuffer() );
ASSERT( strTextBuffer != NULL );
int nTextBufferLen = _tcslen( strTextBuffer );
if( nTextBufferLen > 0 )
{
COLORREF clrTextNew =
OnQueryTextColor(
wndGrid,
dc,
nVisibleColNo,
nVisibleRowNo,
nColNo,
nRowNo,
nColType,
nRowType,
dwAreaFlags,
dwHelperPaintFlags
);
if( clrTextNew != COLORREF(-1L) )
{
COLORREF clrTextLast =
dc.SetTextColor( clrTextNew );
if( clrTextOld == COLORREF(-1L) )
clrTextOld = clrTextLast;
} // if( clrTextNew != COLORREF(-1L) )
CString _strToDraw;
LPTSTR ptr = _strToDraw.GetBuffer( nTextBufferLen + 1 );
ASSERT( ptr != NULL );
for( int i = 0; i < nTextBufferLen; i++, ptr++ )
(*ptr) = _T(’*’);
(*ptr) = _T(’\0’);
_strToDraw.ReleaseBuffer();
dc.DrawText(
_strToDraw,
(RECT *)&rcCellText,
nDrawTextFlags
);
} // if( nTextBufferLen > 0 )
} // if text painting area is not empty
if( clrTextOld != COLORREF(-1L) )
dc.SetTextColor( clrTextOld );
if( hOldFont != NULL )
::SelectObject( dc, hOldFont );
}
Please also put the following line into CPP file
IMPLEMENT_DYNCREATE(
CExtGridCellPassword,
CExtGridCellStringDM
);
but before the MFC’s standard definion of the debug
new
operator:
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
Now you can start to use the
CExtGridCellPassword
cell type instead of Prof-UIS’s string cell type.
Best reagrds, Sergiy.