Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.135.198.49] |
|
Сообщ.
#1
,
|
|
|
Приветствую Вас!
Господа программисты. Предлагаю на Ваш суд статью по организации работы с блоком "FindReplaceDialog" и процедурой-обработчиком событий от этого диалога, для поиска текста в ВАШЕМ документе. Когда передо мной стала задача. То появились следующие проблемы. [x]Примеры из MSDN оказались нерабочими. <-Обидно, платить деньги за нерабочий код [x]Помощь попросил, но не дождался. <-Как часто бывает [x]Найденные примеры не приемлемы. Ну теперь худшее позади! ПРИСТУПИМ Для того чтобы обрабатывать сообщения от Блока диалога необходимо зарегестрировать свое сообщение с константой FINDMSGSTRING. //Регистрируем наше поисковое сообщение... const UINT wm_Find = ::RegisterWindowMessage(FINDMSGSTRING); Далее неоходимо описать свою процедуру обработки, в классе главного окна. //.... public: LRESULT OnFindMSG(WPARAM wParam, LPARAM lParam) //Формируем Обработчик //... //Наша фукция для обработки сообщение от диалога поиска. ON_REGISTERED_MESSAGE(wm_Find, OnFindMSG) //... Если вы хотите искать текст в компоненте CRichEditCtrl то при создании вам необходимо указать флаг ES_NOHIDESEL //.... 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; } Главная процедура обработки /*=========================================================*/ 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) |