Как разрешить меню для Edit Control
В CDialog или другом окне, которое не имеет меню edit
для вырезания (cutting), копирования (copying), и вставки (pasting),
контролы CEdit обрабатывают эти функции через
обычные Windows акселераторы (CTRL+X,V,C, или SHIFT-DELETE,
SHIFT-INSERT, CTRL-INSERT, CTRL-DELETE, и т.д.).Однако в стандартном
приложении MDI или SDI эти опции запрещены.
Это происходит из-за того, что AppWizard присваивает
обработчики меню и клавиши акселераторов
стандартному меню. Поэтому окошко
редактирования никак не реагирует на клавиши
акселераторов. Данная статья показывает, как
добавить в элементы управления edit на форме,
наследованной от CFormView, функции буфера обмена (clipboard).
Если полностью удалить опции меню (не просто
разрешить или запретить) и различные объявления
акселераторов, то никаких конфликтов в Вашем CEdit
не будет и он будет как обычно работать с
функциями буфера обмена. Однако, если Вы захотите
включить функции буфера обмена в стандартном
меню Edit (и соответствующие им кнопки на
тулбаре), то Вам понадобится добавить некоторые
дополнительные обработчики в программу.
- Ваши UPDATE_COMMAND_UI должны будут определять,
действительно элемент управления, который имеет
фокус в данный момент, является CEdit и есть ли в нём
какой-нибудь текст, для которого можно применить
данную операцию.
- Так как Вы имеете пункты меню для Cut, Copy, или Paste
которые привязаны к стандартным акселераторам,
то Вам понадобится написать обработчики для
действий.
Пример по шагам
Этот пример содержит код, который можно добавить,
чтобы позволить вырезать, копировать и вставлять
текст в элемент управления CEdit в CFormView.
- Сперва определяем, действительно элемент
имеющий фокус является CEdit:
// IsEdit: вспомогательная функция для определения, указывает ли
// данный указатель CWnd на элемент управления CEDit.
// Используйте функцию SDK ::GetClassName() так как MFC-шный IsKindOf
// выдаст ошибку, если это не CEdit
BOOL CMyFormView::IsEdit( CWnd* pWnd )
{
ASSERT( pWnd != NULL );
HWND hWnd = pWnd->GetSafeHwnd();
if (hWnd == NULL)
return FALSE;
TCHAR szClassName[6];
return ::GetClassName(hWnd, szClassName, 6) &&
_tcsicmp(szClassName, _T("Edit")) == 0;
}
- Добавляем обработчики UPDATE_COMMAND_UI для ID_EDIT_COPY &
ID_EDIT_CUT:
// UPDATE_COMMAND_UI обработчик для Edit Copy и Edit Cut, которые оба
// требуют, чтобы текущий фокус находился в окошке редактирования,
// которое содержит выделенный текст.
void CMyFormView::OnUpdateNeedSel(CCmdUI* pCmdUI)
{
// получаем текущий фокус и определяем, находится ли он на CEdit
CWnd* pWnd = GetFocus();
if (NULL == pWnd || !IsEdit( pWnd ))
{
pCmdUI->Enable( FALSE );
}
else
{
CEdit* pEdit = (CEdit*)pWnd;
int nBeg, nEnd;
pEdit->GetSel( nBeg, nEnd );
pCmdUI->Enable( nBeg != nEnd );
}
}
- Добавляем обработчики UPDATE_COMMAND_UI для ID_EDIT_PASTE:
// UPDATE_COMMAND_UI обработчики для Edit Paste, требующие, чтобы
// фокус был на окне редактирования и чтобы буфер обмена содержал
// текст, который будет вставлен в контрол.
void CMyFormView::OnUpdateNeedClip(CCmdUI* pCmdUI)
{
// получаем текущий фокус и определяем, находится ли он на CEdit
// а так же проверяем, чтобы элемент управления не был read-only.
CWnd* pWnd = GetFocus();
if ( NULL == pWnd ||
!IsEdit( pWnd ) ||
(pWnd->GetStyle() & ES_READONLY) != 0 )
{
pCmdUI->Enable( FALSE );
}
else
pCmdUI->Enable(::IsClipboardFormatAvailable(CF_TEXT));
}
- Добавляем стандартные обработчики для ID_EDIT_COPY,
ID_EDIT_CUT, и ID_EDIT_PASTE:
void CMyFormView::OnEditCopy()
{
CEdit* pEdit = (CEdit*)GetFocus();
ASSERT( IsEdit( pEdit) );
pEdit->Copy();
}
void CMyFormView::OnEditCut()
{
CEdit* pEdit = (CEdit*)GetFocus();
ASSERT( IsEdit( pEdit) );
pEdit->Cut();
}
void CMyFormView::OnEditPaste()
{
CEdit* pEdit = (CEdit*)GetFocus();
ASSERT( IsEdit( pEdit) );
ASSERT(::IsClipboardFormatAvailable(CF_TEXT));
pEdit->Paste();
}
|