В 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(); } |