GUIFramework 1.1.0
Framework for desktop GUI applications in C++.
Loading...
Searching...
No Matches
BaseMainWindow.cpp
Go to the documentation of this file.
1#include "BaseMainWindow.h"
2
3#include <windowsx.h>
4
5#include "GUIFramework.h"
7
8using namespace std;
9
10namespace gui_framework
11{
12 BaseMainWindow::Function::Function(const function<void()>& callable) :
13 callable(callable)
14 {
15
16 }
17
18 BaseMainWindow::Function::Function(const string& functionName, const string& moduleName) :
19 functionName(functionName),
20 moduleName(moduleName)
21 {
22 GUIFramework& instance = GUIFramework::get();
23 const HMODULE& module = instance.getModules().at(moduleName);
24
25 onClickSignature tem = reinterpret_cast<onClickSignature>(GetProcAddress(module, functionName.data()));
26
27 if (!tem)
28 {
29 throw exceptions::CantFindFunctionFromModuleException(functionName, moduleName, __FILE__, __FUNCTION__, __LINE__);
30 }
31
32 callable = tem;
33 }
34
35 void BaseMainWindow::onDestroyEvent()
36 {
37
38 }
39
40 void BaseMainWindow::createMarkup()
41 {
42
43 }
44
45 LRESULT BaseMainWindow::windowMessagesHandle(HWND handle, UINT message, WPARAM wparam, LPARAM lparam, bool& isUsed)
46 {
47 LRESULT result = BaseSeparateWindow::windowMessagesHandle(handle, message, wparam, lparam, isUsed);
48
49 if (isUsed)
50 {
51 return result;
52 }
53
54 if (message == trayId)
55 {
56 switch (LOWORD(lparam))
57 {
58 case NIN_SELECT:
59 isUsed = true;
60
61 if (++clicks == 2)
62 {
63 if (!alwaysShowTrayIcon)
64 {
65 Shell_NotifyIconW(NIM_DELETE, &tray);
66 }
67
68 show();
69
70 clicks = 0;
71 }
72
73 return 0;
74
75 case WM_CONTEXTMENU:
76 if (trayPopupMenu)
77 {
78 isUsed = true;
79
80 TrackPopupMenuEx(trayPopupMenu, TPM_CENTERALIGN, GET_X_LPARAM(wparam), GET_Y_LPARAM(wparam), this->getHandle(), nullptr);
81
82 return 0;
83 }
84
85 break;
86
87 default:
88 break;
89 }
90 }
91 else if (message == WM_COMMAND && popupMenuItems.size())
92 {
93 uint32_t id = LOWORD(wparam);
94
95 if (auto it = ranges::find_if(popupMenuItems, [id](const pair<uint32_t, Function>& item) { return item.first == id; }); it != popupMenuItems.end())
96 {
97 isUsed = true;
98
99 it->second.callable();
100
101 return 0;
102 }
103 }
104
105 return -1;
106 }
107
108 BaseMainWindow::BaseMainWindow(const wstring& className, const wstring& titleName, const utility::ComponentSettings& settings, const string& windowFunctionName, uint16_t trayIconResource, bool alwaysShowTrayIcon, bool maximize, bool minimize, const string& moduleName, uint16_t smallIconResource, uint16_t largeIconResource) :
110 (
111 className,
112 titleName,
113 settings,
114 windowFunctionName,
115 maximize,
116 minimize,
117 moduleName,
118 smallIconResource,
119 largeIconResource
120 ),
121 tray(),
122 trayPopupMenu(nullptr),
123 trayId(0),
124 clicks(0)
125 {
126 // TODO: localization
127
129
130 this->initTray(trayIconResource, alwaysShowTrayIcon);
131
132 this->setBackgroundColor(240, 240, 240);
133 }
134
135 void BaseMainWindow::initTray(uint16_t trayIconResource, bool alwaysShowTrayIcon)
136 {
137 if (!trayIconResource)
138 {
139 return;
140 }
141
142 this->trayIconResource = trayIconResource;
143 this->alwaysShowTrayIcon = alwaysShowTrayIcon;
144
145 trayId = GUIFramework::get().generateTrayId();
146 trayPopupMenu = CreatePopupMenu();
147
148 tray.cbSize = sizeof(tray);
149 tray.hWnd = getHandle();
150 tray.uFlags = NIF_MESSAGE | NIF_ICON;
151 tray.uCallbackMessage = trayId;
152 tray.uVersion = NOTIFYICON_VERSION_4;
153
154 this->setOnClose
155 (
156 [this]()
157 {
158 if (!this->alwaysShowTrayIcon)
159 {
160 Shell_NotifyIconW(NIM_ADD, &tray);
161
162 Shell_NotifyIconW(NIM_SETVERSION, &tray);
163 }
164
165 hide();
166
167 return false;
168 }
169 );
170
171 this->setOnDestroy
172 (
173 [this]()
174 {
175 Shell_NotifyIconW(NIM_DELETE, &tray);
176
177 this->onDestroyEvent();
178 }
179 );
180
181 LoadIconMetric(GetModuleHandleW(nullptr), MAKEINTRESOURCE(trayIconResource), _LI_METRIC::LIM_LARGE, &tray.hIcon);
182
183 if (alwaysShowTrayIcon)
184 {
185 Shell_NotifyIconW(NIM_DELETE, &tray);
186
187 Shell_NotifyIconW(NIM_ADD, &tray);
188
189 Shell_NotifyIconW(NIM_SETVERSION, &tray);
190 }
191 }
192
193 bool BaseMainWindow::addTrayMenuItem(const wstring& text, const function<void()>& onClick, uint32_t* menuItemId)
194 {
195 if (!trayPopupMenu)
196 {
197 return false;
198 }
199
200 uint32_t id = popupMenuItems.emplace_back(GUIFramework::get().generateTrayId(), onClick).first;
201
202 if (menuItemId)
203 {
204 *menuItemId = id;
205 }
206
207 AppendMenuW(trayPopupMenu, MF_STRING, id, text.data());
208
209 return true;
210 }
211
212 bool BaseMainWindow::addTrayMenuItem(const wstring& text, const string& functionName, const string& moduleName, uint32_t* menuItemId)
213 {
214 if (!trayPopupMenu)
215 {
216 return false;
217 }
218
219 uint32_t id = popupMenuItems.emplace_back(GUIFramework::get().generateTrayId(), Function(functionName, moduleName)).first;
220
221 if (menuItemId)
222 {
223 *menuItemId = id;
224 }
225
226 AppendMenuW(trayPopupMenu, MF_STRING, id, text.data());
227
228 return true;
229 }
230
231 bool BaseMainWindow::removeTrayMenuItem(const wstring& text)
232 {
233 if (!trayPopupMenu)
234 {
235 return false;
236 }
237
238 for (size_t i = 0; i < popupMenuItems.size(); i++)
239 {
240 MENUITEMINFOW info = {};
241
242 info.cbSize = sizeof(info);
243 info.fMask = MIIM_STRING;
244
245 GetMenuItemInfoW(trayPopupMenu, static_cast<uint32_t>(i), true, &info);
246
247 if (info.dwTypeData && info.dwTypeData == text)
248 {
249 popupMenuItems.erase(popupMenuItems.begin() + i);
250
251 DeleteMenu(trayPopupMenu, static_cast<uint32_t>(i), MF_BYPOSITION);
252
253 return true;
254 }
255 }
256
257 return false;
258 }
259
261 {
262 this->sendRawMessage(WM_COMMAND, MAKEWPARAM(id, NULL), NULL);
263 }
264
266 {
267 return typeid(BaseMainWindow).hash_code();
268 }
269
270 json::JSONBuilder BaseMainWindow::getStructure() const
271 {
272 using json::utility::jsonObject;
273
274 json::JSONBuilder builder = BaseSeparateWindow::getStructure();
275 jsonObject& current = get<jsonObject>(builder[utility::to_string(windowName, ISerializable::getCodepage())]);
276
277 if (trayIconResource)
278 {
279 vector<jsonObject> items;
280
281 current.setInt("trayIconResource", trayIconResource);
282
283 current.setBool("alwaysShowTrayIcon", alwaysShowTrayIcon);
284
285 for (size_t i = 0; i < popupMenuItems.size(); i++)
286 {
287 const Function& function = popupMenuItems[i].second;
288
289 if (function.functionName.size())
290 {
291 jsonObject object;
292
293 MENUITEMINFOW info = {};
294
295 info.cbSize = sizeof(info);
296 info.fMask = MIIM_STRING;
297
298 GetMenuItemInfoW(trayPopupMenu, static_cast<uint32_t>(i), true, &info);
299
300 object.setString("text", info.dwTypeData ? utility::to_string(info.dwTypeData, interfaces::ISerializable::getCodepage()) : "");
301
302 object.setString("functionName"s, function.functionName);
303
304 object.setString("moduleName"s, function.moduleName);
305
306 object.setString("pathToModule"s, GUIFramework::get().getModulesPaths().at(function.moduleName));
307
308 json::utility::appendArray(move(object), items);
309 }
310 }
311
312 if (items.size())
313 {
314 current.setArray("items", move(items));
315 }
316 }
317
318 return builder;
319 }
320
322 {
323 if (trayPopupMenu)
324 {
325 DestroyMenu(trayPopupMenu);
326 }
327
328 if (tray.hIcon)
329 {
330 DeleteObject(tray.hIcon);
331
332 tray.hIcon = nullptr;
333 }
334 }
335}
const std::wstring windowName
LRESULT sendRawMessage(UINT message, WPARAM wparam, LPARAM lparam)
SendMessage WinAPI wrapper.
void setOnDestroy(const std::function< void()> &onDestroy)
void setExitMode(exitMode mode)
void sendTrayMessage(uint32_t id)
Process tray commands.
bool removeTrayMenuItem(const std::wstring &text)
Remove tray menu text item.
bool addTrayMenuItem(const std::wstring &text, const std::function< void()> &onClick, uint32_t *menuItemId=nullptr)
Add tray menu text item. Works only if non NULL value passed in trayIconResource in contructor.
BaseMainWindow(const std::wstring &className, const std::wstring &titleName, const utility::ComponentSettings &settings, const std::string &windowFunctionName, uint16_t trayIconResource, bool alwaysShowTray=false, bool maximize=false, bool minimize=false, const std::string &moduleName="", uint16_t smallIconResource=NULL, uint16_t largeIconResource=NULL)
virtual json::JSONBuilder getStructure() const override
virtual size_t getHash() const override
Used as key in creators.
void initTray(uint16_t trayIconResource, bool alwaysShowTrayIcon)
Base class for separate windows.
virtual json::JSONBuilder getStructure() const override
virtual void setBackgroundColor(uint8_t red, uint8_t green, uint8_t blue) final override
static GUIFramework & get()
Singleton instance access.
virtual void setOnClose(const std::function< bool()> &onClose) final
string to_string(wstring_view stringToConvert, uint32_t codepage)
Definition Utility.cpp:41
void(*)() onClickSignature
Default on click signature.
Function(const std::function< void()> &callable)