Как разрешить меню для 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();
}