На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела FAQ в группе разделов С++.
1. Раздел FAQ предназначен для публикации готовых статей.
2. Здесь нельзя задавать вопросы, для этого существуют соответствующие разделы:
Чистый С++
Visual C++ / MFC / WTL / WinApi
Borland C++ Builder
COM / DCOM / ActiveX / ATL
Сопутствующие вопросы
3. Внимание, все темы и сообщения в разделе премодерируются. Любое сообщение или тема будут видны остальным участникам только после одобрения модератора.
Модераторы: B.V., Qraizer
  
> Поиск текста + CFindReplace , RichEdit
    Приветствую Вас!
    Господа программисты.

    Предлагаю на Ваш суд статью по организации работы с блоком "FindReplaceDialog"
    и процедурой-обработчиком событий от этого диалога, для поиска текста в ВАШЕМ документе.

    Когда передо мной стала задача. То появились следующие проблемы.

    [x]Примеры из MSDN оказались нерабочими. <-Обидно, платить деньги за нерабочий код
    [x]Помощь попросил, но не дождался. <-Как часто бывает
    [x]Найденные примеры не приемлемы.

    Ну теперь худшее позади!
    ПРИСТУПИМ

    Для того чтобы обрабатывать сообщения от Блока диалога необходимо
    зарегестрировать свое сообщение с константой FINDMSGSTRING.

    ExpandedWrap disabled
      //Регистрируем наше поисковое сообщение...
      const UINT    wm_Find = ::RegisterWindowMessage(FINDMSGSTRING);


    Далее неоходимо описать свою процедуру обработки, в классе главного окна.

    ExpandedWrap disabled
      //....
      public:
      LRESULT  OnFindMSG(WPARAM wParam, LPARAM lParam)


    ExpandedWrap disabled
      //Формируем Обработчик
                  //...
          //Наша фукция для обработки сообщение от диалога поиска.
          ON_REGISTERED_MESSAGE(wm_Find, OnFindMSG)
                 //...


    Если вы хотите искать текст в компоненте
    CRichEditCtrl то при создании вам необходимо указать флаг ES_NOHIDESEL

    ExpandedWrap disabled
      //....
          m_Re.Create(WS_VISIBLE|WS_CHILD|ES_MULTILINE
              |ES_NOHIDESEL//Не забудьте указать, иначе не будет видно выделения
              |WS_VSCROLL,r,&m_wndView,1000);
       
      //....
       
       
       
      //Оператор обработки меню поиска
      //Обрабатываем вызов диалога поиска
      void CMainFrame::OnTextFind()
      {
          m_FindDialog = new CFindReplaceDialog();
          m_FindDialog->Create(true,"");
          m_FindDialog->m_fr.lStructSize =sizeof(FINDREPLACE);
          m_FindDialog->m_fr.Flags -=FR_ENABLEHOOK;
          m_FindDialog->m_fr.hInstance =AfxGetApp()->m_hInstance;    
          m_FindDialog->m_fr.hwndOwner = this->m_hWnd;
      }


    Главная процедура обработки

    ExpandedWrap disabled
      /*=========================================================*/
      CString m_OldStr; //для запоминания строки
      int OldPos;
      LRESULT  CMainFrame::OnFindMSG(WPARAM wParam, LPARAM lParam)
      {
      LPFINDREPLACE lpFR = (LPFINDREPLACE) lParam;
       
      if(lpFR->Flags & FR_FINDNEXT)
      {
          FINDTEXTEX ft;
          
          //Этот код нужен для того что бы если текст найден то искать следующий текст
          //Иначе  будет найденна только одна строчка и все.
          if(m_OldStr == lpFR->lpstrFindWhat)//Если ИСКАТЬ старую строку
          {
              if(lpFR->Flags & FR_DOWN)
              {
                  ft.chrg.cpMin = OldPos;
              ft.chrg.cpMax =m_Re.GetTextLength();
              }
              else//Если Искать вверх
              {
              ft.chrg.cpMax = 0;
              ft.chrg.cpMin = OldPos;
              }
          }
          else //Если поиск новый
          {
              if(lpFR->Flags & FR_DOWN)  
              {
                  ft.chrg.cpMin = 0;
                  ft.chrg.cpMax = m_Re.GetTextLength();
              }
              else
              {
              ft.chrg.cpMin = m_Re.GetTextLength();
              ft.chrg.cpMax = 0();
              }
          }
          ft.lpstrText = lpFR->lpstrFindWhat;
          /*
          Можно как угодно сформировать алгоритм поиска
          Это остается на Ваше усмотрение.
          */
          //Исчем...
          long n = m_Re.FindText(lpFR->Flags, &ft);
            if (n != -1)
          {
              //Если находим то выделяем
              m_Re.SetSel(ft.chrgText);
              //Запинаем позиции что бы икскать последующие...
              //Если Этого не сделать то поиск остановиться
              if(lpFR->Flags & FR_DOWN)
                         OldPos=ft.chrgText.cpMax; else
              OldPos=ft.chrgText.cpMin;
              m_OldStr = lpFR->lpstrFindWhat;
          }else
          {
              //Если не нашли(или уже найденны все возможные) то
              //Обнуляем наши переменные для нового поиска.
              OldPos =0;
              m_OldStr ="";
              AfxMessageBox("Text not found");
          }
      }
      return 0;
      }

    Именно в этой процедуре OnFindMSG Вы будете производить основные действия по организации
    алгоритмов Вашего поиска.
    Вы можете дабавить в любое место свой код что бы он полностью удовлетворял вашим потребностям.

    Не люблю много теории. Поэтому КОД по возможности, лаконично и понятно закоментированн.

    Досвидания!
    Ваш ASTER_X == aster_x <at> inbox <dot> ru
    Прикреплённый файлПрикреплённый файлFindDemo.zip (52.44 Кбайт, скачиваний: 190)
    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
    0 пользователей:


    Рейтинг@Mail.ru
    [ Script execution time: 0,0216 ]   [ 15 queries used ]   [ Generated: 1.05.24, 19:56 GMT ]