How to find text within a multi-line rich edit wxTextCtrl? Topic is solved
-
- Experienced Solver
- Posts: 64
- Joined: Tue Sep 11, 2007 6:02 pm
- Location: Brazil
How to find text within a multi-line rich edit wxTextCtrl?
Hi everybody. I'm new to wxWidgets, please be patient...
Using mingw gcc 3.4.2, Win XP, wxWidgets 2.8.4
I tried going to the API doing this:
HWND handle = (HWND) ctrl->GetHandle();
FINDTEXT ft;
LONG retval;
ft.lpstrText = wxStringBuffer(text,text.Len());
// "text" is a wxString with the text to search for
ft.chrg.cpMin = from;
ft.chrg.cpMax = to;
options |= 1;
// "options" is the WPARAM, meant to be or'ed with one of
// the following
// FR_DOWN 1
// FR_MATCHCASE 4
// FR_WHOLEWORD 2
retval = ::SendMessage(handle, EM_FINDTEXT, options, (LPARAM)&ft);
No matter what I do, retval is set to -1, which means the text wasn't found.
The new wxRichTextCtrl isn't suitable for what I need, since being able to read rtf files is an absolute need for me...
I really need this to port an app to wxWidgets, I feel that I hit a wall, any help will be greatly appreciated.
Thanks in advance,
Ken
Using mingw gcc 3.4.2, Win XP, wxWidgets 2.8.4
I tried going to the API doing this:
HWND handle = (HWND) ctrl->GetHandle();
FINDTEXT ft;
LONG retval;
ft.lpstrText = wxStringBuffer(text,text.Len());
// "text" is a wxString with the text to search for
ft.chrg.cpMin = from;
ft.chrg.cpMax = to;
options |= 1;
// "options" is the WPARAM, meant to be or'ed with one of
// the following
// FR_DOWN 1
// FR_MATCHCASE 4
// FR_WHOLEWORD 2
retval = ::SendMessage(handle, EM_FINDTEXT, options, (LPARAM)&ft);
No matter what I do, retval is set to -1, which means the text wasn't found.
The new wxRichTextCtrl isn't suitable for what I need, since being able to read rtf files is an absolute need for me...
I really need this to port an app to wxWidgets, I feel that I hit a wall, any help will be greatly appreciated.
Thanks in advance,
Ken
-
- Experienced Solver
- Posts: 64
- Joined: Tue Sep 11, 2007 6:02 pm
- Location: Brazil
Thanks for the answer, but that's how I got there in the first place... I can't find a way to locate a substring within a wxTextCtrl, I'd appreciate any suggestions in that regard.protocol wrote:It's probably best that you use wxWidget classes (wxTextCtrl & wxString) to find the text.
best regards.
Ken
-
- Experienced Solver
- Posts: 64
- Joined: Tue Sep 11, 2007 6:02 pm
- Location: Brazil
And an addendum: I managed to extract the text from the control and place it a wxString, where I can use Find() to search for the first occurrence of the character sequence. But I really need to find repeated occurrences of that sequence within the wxString...Kenneth Camargo wrote:Thanks for the answer, but that's how I got there in the first place... I can't find a way to locate a substring within a wxTextCtrl, I'd appreciate any suggestions in that regard.protocol wrote:It's probably best that you use wxWidget classes (wxTextCtrl & wxString) to find the text.
best regards.
Ken
Still hoping from some help,
Ken
For repeated matches, you can continuously call wxString::find('TEXT', FIND_POS), until it stops returning a valid result or until the end of the string.
http://www.wxwidgets.org/manuals/stable ... wxstringat
best regards.
http://www.wxwidgets.org/manuals/stable ... wxstringat
Code: Select all
// All find() functions take the nStart argument which specifies the
// position to start the search on, the default value is 0. All functions
// return npos if there were no match.
// find a substring
size_t find(const wxString& str, size_t nStart = 0) const;
-
- Experienced Solver
- Posts: 64
- Joined: Tue Sep 11, 2007 6:02 pm
- Location: Brazil
Hi - I still have to copy the contents of the control into a wxString, I'm afraid this might be a problem if the size of the text is too big - isn't there a way to retrieve that information without dumping all the data from the control to another buffer?protocol wrote:For repeated matches, you can continuously call wxString::find('TEXT', FIND_POS), until it stops returning a valid result or until the end of the string.
http://www.wxwidgets.org/manuals/stable ... wxstringat
best regards.Code: Select all
// All find() functions take the nStart argument which specifies the // position to start the search on, the default value is 0. All functions // return npos if there were no match. // find a substring size_t find(const wxString& str, size_t nStart = 0) const;
And thanks for the hint,
Ken
wxTextCtrl has no built-in 'Find' functions that I know about.
Check it out: http://www.wxwidgets.org/manuals/stable ... wxtextctrl
You may just want to edit the source (of wxTextCtrl) and implement your own 'FindText' method.
best regards.
Check it out: http://www.wxwidgets.org/manuals/stable ... wxtextctrl
Code: Select all
int position = myTextCtrl.GetValue().find('this_text', start_pos)
best regards.
-
- Experienced Solver
- Posts: 64
- Joined: Tue Sep 11, 2007 6:02 pm
- Location: Brazil
Thanks once again. That still copies the text, I think, but that'll have to do for the moment, I'm too much of a newbie to dare tweaking the internals...protocol wrote:wxTextCtrl has no built-in 'Find' functions that I know about.
Check it out: http://www.wxwidgets.org/manuals/stable ... wxtextctrlYou may just want to edit the source (of wxTextCtrl) and implement your own 'FindText' method.Code: Select all
int position = myTextCtrl.GetValue().find('this_text', start_pos)
best regards.
Regards,
Ken
-
- Experienced Solver
- Posts: 64
- Joined: Tue Sep 11, 2007 6:02 pm
- Location: Brazil
Hi all,
I'm trying to do similar function (search in multiline wxTextCtrl) recently, and I encountered the "\n" vs "\r\n" problem. Though I have a solution, but I don't think it's a perfect one. Now I'll list what I have known, and if you have any good ideas, please kindly share your comments.
(The environment I'm using: WinXP, VC++ Express 2008, wxWidgets 2.8.9)
The goal is:
Then I found that this doesn't work. The selected text is a few chars ahead the actual target if new-line is encountered.
I looked up the manual and realized that it's the \r\n problem. Then I did some tests to check how wxTextCtrl member functions deal with the new line characters:
I found a work-around after digging into the implementation of wxTextCtrl::GetRange():
It's workable, but I don't think it's a good solution because:
I'm trying to do similar function (search in multiline wxTextCtrl) recently, and I encountered the "\n" vs "\r\n" problem. Though I have a solution, but I don't think it's a perfect one. Now I'll list what I have known, and if you have any good ideas, please kindly share your comments.
(The environment I'm using: WinXP, VC++ Express 2008, wxWidgets 2.8.9)
The goal is:
- Search for a phrase from the insertion point to the end of a wxTextCtrl object.
- If found, move the insertion point to the phrase and select it.
- If not found, show message in status bar.
Code: Select all
// Search text from the insertion point to the end.
start = m_textCtrl->GetInsertionPoint();
result = m_textCtrl->GetRange( start, m_textCtrl->GetLastPosition()).find( strTarget.c_str(), 0);
if ( result != wxNOT_FOUND)
{
result += start; // 'result' is an offset from 'start', so 'start' have to be added back
m_textCtrl->SetFocus();
m_textCtrl->SetInsertionPoint( result);
m_textCtrl->SetSelection( result, result + strTarget.Length());
}
else
{
m_statusBar1->SetStatusText( wxT("Not found."));
}
I looked up the manual and realized that it's the \r\n problem. Then I did some tests to check how wxTextCtrl member functions deal with the new line characters:
- Get/SetInsertionPoint() : Treats new-line as \r\n.
- GetLastPosition() : Treats new-line as \r\n.
- GetRange() : Treats new-line as \r\n when calculating the start/end position, but the wxString returned contains \n only.
- SetSelection() : Treats new-line as \r\n.
I found a work-around after digging into the implementation of wxTextCtrl::GetRange():
Code: Select all
start = m_textCtrl->GetInsertionPoint();
// manually translate the wxString object returned from GetRange() into DOS format
wxString tmp = wxTextFile::Translate( m_textCtrl->GetRange( start, m_textCtrl->GetLastPosition()), wxTextFileType_Dos);
result = tmp.find( strTarget.c_str(), 0);
// skipped...
- The wxTextFile::Translate() is undocumented.
- It's not portable.
- The string has to be copied/translated redaundantly.
(There is already a translation from DOS to Unix inside GetRange(), but I have to translate it back....)
- Create a new member function wxTextCtrl::Find() who returns index that can be used by other member functions,
- wxTextCtrl::GetRange() should return text with \r\n so that all member functions uses the same index system, or
- All member functions should treats new-line as \n since the internal data is so. (the most portable way)
protocol,protocol wrote:closer: I use multi-line text searching in QuRegExmm. Check out the source code on sourceforge.
I downloaded QuRegExmm and looked into the sources. I found that you used wxRegEx in QuRegExmm, so I tried the similar way in my code. Unfortunately, the result is still the same.
However, when I tried to implement the highlight function by turning on the wxTE_RICH flag, suddenly it worked -- whether wxRegEx or wxString::find() was used. In this case, all functions I described in the last post treats newline as \n, no more \n vs \r\n problems now!
I haven't traced into wxTextCtrl again yet, but it seems that different methods are applied when simple text control or rich-edit is used... Well, it's a little confusing to me. (Is it a bug or a feature?)
Thanks for your sources anyway.