| Код | ///////////////////////////////////////////////////////////////////////////// // Local utility functions
// // RTF edit control StreamIn's callback function // - see CRichEditCtrl::StreamIn // static DWORD CALLBACK _LoadRtfCallback( DWORD dwCookie, // (in) pointer to the string LPBYTE pbBuff, // (in) pointer to the destination buffer LONG cb, // (in) size in bytes of the destination buffer LONG FAR *pcb // (out) number of bytes transfered ) { LPCTSTR pszMsg = (LPCTSTR)dwCookie;
// number of bytes to copy *pcb = _tcslen( pszMsg ) * sizeof(TCHAR);
// limiting it up to the buffer's size if( *pcb > cb ) *pcb = cb;
// copying the string to the buffer memcpy( pbBuff, pszMsg, *pcb );
// advancing to the end of the string pszMsg += *pcb / sizeof(TCHAR);
// if it's the end of the string, returns NULL; // otherwise, returns a pointer to the next char to transfer as the cookie return ( *pszMsg != '\0' ) ? (DWORD)pszMsg : NULL; } void CTcxMsgBox::CreateRtfCtrl() { // Creating the Rich Edit control
CRect rcDummy; // dimesion doesn't matter here
m_edCtrl.Create( WS_CHILD|WS_VISIBLE|ES_LEFT|ES_MULTILINE|ES_READONLY, rcDummy, this, (UINT)IDC_STATIC ); m_edCtrl.SetBackgroundColor( FALSE, ::GetSysColor( COLOR_3DFACE ) ); m_edCtrl.SetFont( GetFont() );
if( m_bRtf ) { // Loading a RTF message EDITSTREAM es; es.dwCookie = (DWORD)(LPCTSTR)m_strMsg; es.dwError = 0; es.pfnCallback = _LoadRtfCallback;
m_edCtrl.StreamIn( SF_RTF, es ); } else { // Loading a plain text message m_edCtrl.SetWindowText( m_strMsg ); }
///////////////////////////////////////////////////////// // Calculating the best Rich Edit control dimension // // Note: // There's no Rich Edit operation to get the minimum // width it needs to show its contents without line // breaks. However, given a width, we can check // how much height it needs to show its text (see // bottomless rich edit controls). // We'll this mechanism to perform a binary search // and find that best width value.
m_edCtrl.SetEventMask( ENM_REQUESTRESIZE );
m_dimMsg.cx = 0; m_dimMsg.cy = 0;
// Performing a binary search for the best dimension
int cxFirst = 0; int cxLast = ::GetSystemMetrics( SM_CXFULLSCREEN ); int cyMax = 0;
do { // taking a guess int cx = ( cxFirst + cxLast ) / 2;
// testing it CRect rc( 0, 0, cx, 1 ); m_edCtrl.MoveWindow( rc ); m_edCtrl.RequestResize();
// if it's the first guess, take it anyway if( cyMax == 0 ) cyMax = m_dimMsg.cy; // refining the guess if( m_dimMsg.cy > cyMax ) { cxFirst = cx + 1; } else { cxLast = cx - 1; } } while( cxFirst < cxLast ); }
|
|