GUIFramework 1.1.0
Framework for desktop GUI applications in C++.
Loading...
Searching...
No Matches
BaseRichEdit.cpp
Go to the documentation of this file.
1#include "BaseRichEdit.h"
2
4#include "GUIFramework.h"
5
7
8using namespace std;
9
10namespace gui_framework
11{
12 void BaseRichEdit::addCallback(urlDetectEvent event, const function<void(const wstring&)>& callback, const string& functionName, const string& moduleName)
13 {
14 if (event == urlDetectEvent::setCursor)
15 {
16 callbacks[7] = callback;
17
18 callbacksFunctionNamesAndModules[7] = make_pair(functionName, moduleName);
19 }
20 else
21 {
22 callbacks[static_cast<size_t>(event) % urlDetectEventSize] = callback;
23
24 callbacksFunctionNamesAndModules[static_cast<size_t>(event) % urlDetectEventSize] = make_pair(functionName, moduleName);
25 }
26 }
27
28 LRESULT BaseRichEdit::windowMessagesHandle(HWND handle, UINT message, WPARAM wparam, LPARAM lparam, bool& isUsed)
29 {
30 isUsed = false;
31
32 if (message == WM_NOTIFY && this->getAutoURLDetect())
33 {
34 NMHDR* notification = reinterpret_cast<NMHDR*>(lparam);
35
36 if (notification->code == EN_LINK)
37 {
38 ENLINK* ptrLink = reinterpret_cast<ENLINK*>(lparam);
39
40 const function<void(const wstring&)>& callback = this->getCallback(static_cast<urlDetectEvent>(ptrLink->msg));
41
42 if (callback)
43 {
44 isUsed = true;
45
46 callback
47 (
48 this->getText().substr
49 (
50 ptrLink->chrg.cpMin,
51 static_cast<size_t>(ptrLink->chrg.cpMax) - ptrLink->chrg.cpMin
52 )
53 );
54
55 return 0;
56 }
57 }
58 }
59
60 return -1;
61 }
62
63 BaseRichEdit::BaseRichEdit(const wstring& richEditName, const utility::ComponentSettings& settings, BaseComposite* parent, bool isMultiLine) :
65 (
66 standard_classes::richEdit,
67 richEditName,
68 settings,
69 styles::DefaultRichEditStyles(isMultiLine),
70 parent
71 ),
72 IResizableComponent
73 (
74 handle,
75 parent ? parent->getHandle() : nullptr
76 ),
77 ITextOperations(handle),
78 isMultiLine(isMultiLine),
79 limitTextCount(0)
80 {
81 this->setText(L"");
82
83 ranges::for_each(callbacks, [](function<void(const wstring&)>& callback) { callback = nullptr; });
84
85 ranges::for_each(callbacksFunctionNamesAndModules, [](pair<string, string>& data) { data = make_pair(""s, ""s); });
86 }
87
88 void BaseRichEdit::addUrlDetectEvent(urlDetectEvent event, const function<void(const wstring&)>& eventCallback)
89 {
90 this->addCallback(event, eventCallback, ""s, ""s);
91 }
92
93 void BaseRichEdit::addUrlDetectEvent(urlDetectEvent event, const string& functionName, const string& moduleName)
94 {
95 GUIFramework& instance = GUIFramework::get();
96 const HMODULE& module = instance.getModules().at(moduleName);
97
98 richEditCallbackSignature tem = reinterpret_cast<richEditCallbackSignature>(GetProcAddress(module, functionName.data()));
99
100 if (!tem)
101 {
102 throw exceptions::CantFindFunctionFromModuleException(functionName, moduleName, __FILE__, __FUNCTION__, __LINE__);
103 }
104
105 this->addCallback(event, tem, functionName, moduleName);
106 }
107
109 {
110 if (event == urlDetectEvent::setCursor)
111 {
112 callbacks[7] = nullptr;
113
114 callbacksFunctionNamesAndModules[7] = make_pair(""s, ""s);
115 }
116 else
117 {
118 callbacks[static_cast<size_t>(event) % urlDetectEventSize] = nullptr;
119
120 callbacksFunctionNamesAndModules[static_cast<size_t>(event) % urlDetectEventSize] = make_pair(""s, ""s);
121 }
122 }
123
124 LRESULT BaseRichEdit::findSubstring(const wstring& subStringToFind, bool isMatchCase)
125 {
126 FINDTEXTEXW findText;
127
128 findText.chrg.cpMin = 0;
129 findText.chrg.cpMax = -1;
130
131 findText.lpstrText = subStringToFind.data();
132
133 return SendMessageW(handle, EM_FINDTEXTEXW, NULL | FR_DOWN | (isMatchCase ? FR_MATCHCASE : NULL), reinterpret_cast<LPARAM>(&findText));
134 }
135
136 LRESULT BaseRichEdit::findString(const wstring& stringToFind, bool isMatchCase)
137 {
138 FINDTEXTEXW findText;
139
140 findText.chrg.cpMin = 0;
141 findText.chrg.cpMax = -1;
142
143 findText.lpstrText = stringToFind.data();
144
145 return SendMessageW(handle, EM_FINDTEXTEXW, FR_WHOLEWORD | FR_DOWN | (isMatchCase ? FR_MATCHCASE : NULL), reinterpret_cast<LPARAM>(&findText));
146 }
147
148 void BaseRichEdit::setAutoURLDetect(bool autoURLDetect)
149 {
150 if (autoURLDetect)
151 {
152 SendMessageW(handle, EM_SETEVENTMASK, NULL, SendMessageW(handle, EM_GETEVENTMASK, NULL, NULL) | ENM_LINK);
153
154 SendMessageW(handle, EM_AUTOURLDETECT, AURL_ENABLEURL, NULL);
155 }
156 else
157 {
158 SendMessageW(handle, EM_SETEVENTMASK, NULL, SendMessageW(handle, EM_GETEVENTMASK, NULL, NULL) & ~ENM_LINK);
159
160 SendMessageW(handle, EM_AUTOURLDETECT, NULL, NULL);
161 }
162 }
163
164 void BaseRichEdit::setLimitText(uint64_t count)
165 {
166 limitTextCount = count;
167
168 SendMessageW(handle, EM_EXLIMITTEXT, NULL, count);
169 }
170
172 {
173 return SendMessageW(handle, EM_GETAUTOURLDETECT, NULL, NULL);
174 }
175
177 {
178 CHARRANGE range;
179
180 SendMessageW(handle, EM_EXGETSEL, NULL, reinterpret_cast<LPARAM>(&range));
181
182 return this->getText().substr(range.cpMin, static_cast<size_t>(range.cpMax) - range.cpMin);
183 }
184
185 const function<void(const wstring&)>& BaseRichEdit::getCallback(urlDetectEvent event) const
186 {
187 if (event == urlDetectEvent::setCursor)
188 {
189 return callbacks[7];
190 }
191
192 return callbacks[static_cast<size_t>(event) % urlDetectEventSize];
193 }
194
196 {
197 return isMultiLine;
198 }
199
200 void BaseRichEdit::setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue)
201 {
202 BaseComponent::setBackgroundColor(red, green, blue);
203
204 SendMessageW(handle, EM_SETBKGNDCOLOR, NULL, static_cast<LPARAM>(backgroundColor));
205 }
206
207 void BaseRichEdit::setTextColor(uint8_t red, uint8_t green, uint8_t blue)
208 {
209 BaseComponent::setTextColor(red, green, blue);
210
211 CHARFORMAT2W textFormat;
212
213 textFormat.cbSize = sizeof(CHARFORMAT2W);
214 textFormat.dwMask = CFM_COLOR;
215 textFormat.crTextColor = RGB(red, green, blue);
216 textFormat.dwEffects = NULL;
217
218 SendMessageW(handle, EM_SETCHARFORMAT, SCF_ALL, reinterpret_cast<LPARAM>(&textFormat));
219 }
220
221 json::JSONBuilder BaseRichEdit::getStructure() const
222 {
223 using json::utility::jsonObject;
224
225 pair<string, string> emptyPair = make_pair(""s, ""s);
226 json::JSONBuilder builder = BaseComponent::getStructure();
227 jsonObject& current = get<jsonObject>(builder[utility::to_string(windowName, ISerializable::getCodepage())]);
228 vector<jsonObject> jsonCallbacks;
229 const auto& modulesPaths = GUIFramework::get().getModulesPaths();
230
231 current.data.push_back({ "isMultiLine"s, isMultiLine });
232
233 current.data.push_back({ "limitTextCount"s, limitTextCount });
234
235 for (size_t i = 0; i < callbacksFunctionNamesAndModules.size(); i++)
236 {
237 if (callbacksFunctionNamesAndModules[i] == emptyPair)
238 {
239 continue;
240 }
241
242 jsonObject object;
243
244 object.data.push_back({ "callbackType"s, static_cast<uint64_t>(i) });
245
246 object.data.push_back({ "callbackName"s, callbacksFunctionNamesAndModules[i].first });
247
248 object.data.push_back({ "callbackModule"s, modulesPaths.at(callbacksFunctionNamesAndModules[i].second) });
249
250 json::utility::appendArray(move(object), jsonCallbacks);
251 }
252
253 current.data.push_back({ "callbacks"s, move(jsonCallbacks) });
254
255 return builder;
256 }
257}
Base class for all windows, controls, etc.
virtual json::JSONBuilder getStructure() const override
virtual void setTextColor(uint8_t red, uint8_t green, uint8_t blue)
const std::wstring windowName
virtual void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue)
Base class for all windows that has children windows.
virtual void setLimitText(uint64_t count) final
std::array< std::pair< std::string, std::string >, urlDetectEventSize > callbacksFunctionNamesAndModules
virtual void setTextColor(uint8_t red, uint8_t green, uint8_t blue) final override
virtual LRESULT findString(const std::wstring &stringToFind, bool isMatchCase=true) final
virtual std::wstring getSelectedText() const final
virtual bool getIsMultiLine() const final
BaseRichEdit(const std::wstring &richEditName, const utility::ComponentSettings &settings, BaseComposite *parent, bool isMultiLine=false)
virtual LRESULT windowMessagesHandle(HWND handle, UINT message, WPARAM wparam, LPARAM lparam, bool &isUsed) override
virtual json::JSONBuilder getStructure() const override
static constexpr uint8_t urlDetectEventSize
virtual void setAutoURLDetect(bool autoURLDetect) final
std::array< std::function< void(const std::wstring &)>, urlDetectEventSize > callbacks
virtual const std::function< void(const std::wstring &)> & getCallback(urlDetectEvent event) const final
virtual void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) final override
virtual LRESULT findSubstring(const std::wstring &subStringToFind, bool isMatchCase=true) final
virtual void removeUrlDetectEvent(urlDetectEvent event) final
virtual bool getAutoURLDetect() const final
virtual void addUrlDetectEvent(urlDetectEvent event, const std::function< void(const std::wstring &)> &eventCallback) final
const std::unordered_map< std::string, std::string > & getModulesPaths() const
Get all loaded modules paths.
static GUIFramework & get()
Singleton instance access.
void setText(std::wstring_view text)
virtual std::wstring getText() const final
Get text from control.
string to_string(wstring_view stringToConvert, uint32_t codepage)
Definition Utility.cpp:41
void(*)(const std::wstring &) richEditCallbackSignature
Used in rich edit auto url detect events.