"AND" "OR"
Главная Информер Журнал Форум

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

  1. Сперва определяем, действительно элемент имеющий фокус является 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;
       } 



  2. Добавляем обработчики 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 );
          }
       } 



  3. Добавляем обработчики 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));
       } 



  4. Добавляем стандартные обработчики для 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();
       }