Добавьте записи карты сообщений для WM_GETTEXT
и WM_GETTEXTLENGTH
в производный класс CEdit
:
BEGIN_MESSAGE_MAP( CMyEdit, CEdit )
ON_WM_GETTEXT()
ON_WM_GETTEXTLENGTH()
END_MESSAGE_MAP()
Поскольку мы переопределяем эти сообщения, нам нужен метод получения исходного текста элемента управления редактирования без бесконечной рекурсии. Для этого мы можем напрямую вызвать оконную процедуру по умолчанию, которая называется DefWindowProc
:
CStringW CMyEdit::GetTextInternal()
{
CStringW text;
LRESULT len = DefWindowProcW( WM_GETTEXTLENGTH, 0, 0 );
if( len > 0 )
{
// WPARAM = len + 1 because the length must include the null terminator.
len = DefWindowProcW( WM_GETTEXT, len + 1, reinterpret_cast<LPARAM>( text.GetBuffer( len ) ) );
text.ReleaseBuffer( len );
}
return text;
}
Следующий метод получает исходный текст окна и преобразует его. Здесь было бы возможно все, включая пример преобразования между шестнадцатеричным и dec. Для простоты я просто заключаю текст в тире.
CStringW CMyEdit::GetTransformedText()
{
CStringW text = GetTextInternal();
return L"--" + text + L"--";
}
Теперь идет фактический обработчик для WM_GETTEXT
, который копирует преобразованный текст в выходной буфер.
int CMyEdit::OnGetText( int cchDest, LPWSTR pDest )
{
// Sanity checks
if( cchDest <= 0 || ! pDest )
return 0;
CStringW text = GetTransformedText();
// Using StringCchCopyExW() to make sure that we don't write outside of the bounds of the pDest buffer.
// cchDest defines the maximum number of characters to be copied, including the terminating null character.
LPWSTR pDestEnd = nullptr;
HRESULT hr = StringCchCopyExW( pDest, cchDest, text.GetString(), &pDestEnd, nullptr, 0 );
// If our text is greater in length than cchDest - 1, the function will truncate the text and
// return STRSAFE_E_INSUFFICIENT_BUFFER.
if( SUCCEEDED( hr ) || hr == STRSAFE_E_INSUFFICIENT_BUFFER )
{
// The return value is the number of characters copied, not including the terminating null character.
return pDestEnd - pDest;
}
return 0;
}
Обработчик для WM_GETTEXTLENGTH
говорит сам за себя:
UINT CMyEdit::OnGetTextLength()
{
return GetTransformedText().GetLength();
}
person
zett42
schedule
27.10.2017
CMFCMaskedEdit
или вместо этого вы можете управлять классом уCMFCMaskedEdit
.CMFCMaskedEdit
происходит отCEdit
- person Barmak Shemirani   schedule 27.10.2017"VS-path\VC\atlmfc\src\mfc"
, расположение зависит от версии VS.CMFCMaskedEdit
перехватывает ввод и проверяет по маске. - person Barmak Shemirani   schedule 27.10.2017WM_GETTEXT
внутри. Вместо этого он читает непосредственно из своего внутреннего строкового буфера. В противном случаеCMFCMaskedEdit
не сработало бы. Вы также можете проверить это, установив точку останова в переопределенном обработчикеOnGetText()
. Он никогда не сработает, если вы не вызоветеGetWindowText()
или не отправитеWM_GETTEXT
явно. - person zett42   schedule 27.10.2017