Как CRichEditCtrl узнает, что была выполнена операция вставки? - PullRequest
3 голосов
/ 12 февраля 2010

У него есть такие методы, как CRichEditCtrl::Copy(), CRichEditCtrl::Paste(), которые вы можете вызывать, но я не могу обнаружить ни одного сообщения, которое элемент управления отправляет Windows, сообщая ему выполнить операцию вставки. Кто-нибудь знает, существует ли такая вещь? Или CRichEditCtrl делает что-то более низкое, например, мониторинг событий WM_CHAR? Если да, могу ли я повторно использовать какие-либо внутренние методы или мне просто нужно свернуть свои собственные, чтобы переопределить стандартную функциональность вставки?

На самом деле я хочу, чтобы мой пользовательский подкласс (CMyRichEditCtrl : CRichEditCtrl) игнорировал любое форматирование текста, вставленного в в элемент управления. Либо получая данные буфера обмена в другом формате, либо вставляя их как обычно и немедленно удаляя форматирование вставленного текста.

Что я пробовал до сих пор:

  1. Проверка сообщения для WM_PASTE в CMyRichEditCtrl::PreTranslateMessage()
  2. Создание метода virtual void CMyRichEditCtrl::Paste()
  3. Установка точки останова на CRichEditCtrl::Paste() в afxcmn.inl
  4. Сброс каждое сообщение, проходящее через CMyRichEditCtrl::PreTranslateMessage()

Результаты:

1: сообщение WM_PASTE не обнаружено
2: Это никогда не называется
3: Это никогда не ударил ... как?
4: Элемент управления никогда не получает никаких сообщений WM_COMMAND, WM_PASTE или фокусировки. В основном только сообщения о перемещении мыши и нажатии клавиши .

Кажется, другие люди действительно сделали это успешно. Мне интересно, может ли моя версия MFC или что-то испортить, на данный момент.

Ответы [ 5 ]

2 голосов
/ 15 февраля 2010

Обработка сообщения EN_PROTECTED.

ON_NOTIFY_REFLECT(EN_PROTECTED, &YourClass::OnProtected)

// call this from the parent class
void YourClass::Initialize()
{
    CHARFORMAT format = { sizeof(CHARFORMAT) };
    format.dwEffects = CFE_PROTECTED; 
    format.dwMask = CFM_PROTECTED;

    SetDefaultCharFormat(format);
    SetEventMask(ENM_PROTECTED);
}

void YourClass::OnProtected(NMHDR* pNMHDR, LRESULT* pResult)
{
    *pResult = 0; 

    ENPROTECTED* pEP = (ENPROTECTED*)pNMHDR;
    if (pEP->msg == WM_PASTE)
        pResult = 1; // prevent paste
}
0 голосов
/ 28 сентября 2011

я должен выступить, как показано ниже

void MyRichEcit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{


if( ( GetKeyState(VK_CONTROL)<0 && nChar==88 ) || (nChar==VK_DELETE && GetKeyState(VK_SHIFT) < 0) ) //cut
    {

    }

if( ( GetKeyState(VK_CONTROL)<0 && nChar==86 ) || (nChar==VK_INSERT && GetKeyState(VK_SHIFT) < 0) ) //paste
    {

    }


    CWnd::OnKeyDown(nChar, nRepCnt, nFlags);    
}
0 голосов
/ 19 февраля 2010

Используйте макрос ON_MESSAGE в производном классе.

ON_MESSAGE (WM_PASTE, OnPaste)

LRESULT CMyRichEditCtrl :: OnPaste (WPARAM, LPARAM)

Если вы откроете файл RichEdit.h, вы заметите, что некоторые сообщения находятся в диапазоне WM_USER. Возможно, именно так MFC обрабатывает события для элемента управления Rich Edit.

0 голосов
/ 12 февраля 2010

Что происходит, когда пользователь запрашивает действие вставки, как правило, когда сообщение WM_COMMAND с идентификатором ID_EDIT_PASTE отправляется в элемент управления rich edit. По умолчанию в MFC это обрабатывается CRichEditCtrl :: OnEditPaste (), который вызывает Paste () для самого элемента управления редактирования.

Я бы выбрал класс для этого из CRichEditCtrl, добавил метод OnEditPaste и направил ему сообщение с помощью

ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)

декларация, которая должна работать. Кроме того, в вашем PreTranslateMessage вы можете искать WM_COMMAND с wParam ID_EDIT_PASTE.

Кстати, я решил проблему, очень похожую на вашу (вставить без форматирования), просто реализовав OnEditPaste с

void MyRichEdit::OnEditPaste()
{
  SendMessage(EM_PASTESPECIAL,CF_UNICODETEXT);
}

Это отвечает на запрос вставки, отправляя сообщение вставки в элемент управления, который настаивает на том, что формат данных представляет собой простой текст.

Наконец, я должен отметить, что вышеупомянутой техники достаточно, чтобы перехватить все вставки, запускаемые из пользовательского интерфейса. Однако он не будет отлавливать программно-запускаемые вставки, когда ваш код отправляет WM_PASTE в элемент управления редактирования. В этих случаях проще всего просто изменить свой код. Однако, если вы действительно хотите перехватывать такие случаи, вам нужно запачкать руки с помощью COM и IRichEditOleCallback :: QueryAcceptData. Но вы почти наверняка не хотите туда идти: -)

0 голосов
/ 12 февраля 2010

Windows определяет сообщения для вырезания / копирования / вставки. см. WM_CUT .

Вероятно, он отвечает на эти сообщения, а не на сообщения WM_CHAR, чтобы знать, когда выполнять операции с буфером обмена.

...