From 9c928aec759855e28ea3f71ad7cb9db3ea9d6aaa Mon Sep 17 00:00:00 2001 From: pit-ray Date: Thu, 15 Feb 2024 13:37:59 +0900 Subject: [PATCH] update docs --- docs/fluent__tray_8hpp.html | 19 + docs/fluent__tray_8hpp_source.html | 2486 ++++++++++++++-------------- docs/globals.html | 1 + docs/globals_defs.html | 1 + docs/index.html | 7 +- docs/search/all_5.js | 9 +- docs/search/defines_0.js | 3 +- 7 files changed, 1281 insertions(+), 1245 deletions(-) diff --git a/docs/fluent__tray_8hpp.html b/docs/fluent__tray_8hpp.html index 20eb3fa..09e4e82 100644 --- a/docs/fluent__tray_8hpp.html +++ b/docs/fluent__tray_8hpp.html @@ -126,6 +126,9 @@ #define FLUENT_TRAY_MESSAGE_ID_OFFSET   (25)  Unique message identifier.
  +#define FLUENT_TRAY_COLORPICK_OFFSET   (5) + Pixel offset to determine the background color.
+  @@ -172,6 +175,22 @@
Author
pit-ray
Date
2024

Macro Definition Documentation

+ +

◆ FLUENT_TRAY_COLORPICK_OFFSET

+ +
+
+

Enumerations

+ + + +
#define FLUENT_TRAY_COLORPICK_OFFSET   (5)
+
+ +

Pixel offset to determine the background color.

+ +
+

◆ FLUENT_TRAY_MESSAGE_ID_OFFSET

diff --git a/docs/fluent__tray_8hpp_source.html b/docs/fluent__tray_8hpp_source.html index 0f4ef1f..9b22f62 100644 --- a/docs/fluent__tray_8hpp_source.html +++ b/docs/fluent__tray_8hpp_source.html @@ -160,1392 +160,1406 @@
82#define FLUENT_TRAY_MESSAGE_ID_OFFSET (25)
83#endif
84
-
89namespace fluent_tray
-
90{
-
91 static constexpr int MESSAGE_ID = WM_APP + FLUENT_TRAY_MESSAGE_ID_OFFSET ;
+
85#ifndef FLUENT_TRAY_COLORPICK_OFFSET
+
89#define FLUENT_TRAY_COLORPICK_OFFSET (5)
+
90#endif
+
91
92
-
97 namespace util
-
98 {
-
-
106 bool string2wstring(const std::string& str, std::wstring& wstr) {
-
107 if(str.empty()) {
-
108 wstr.clear() ;
-
109 return true ;
-
110 }
-
111
-
112 auto needed_size = MultiByteToWideChar(
-
113 CP_UTF8, 0,
-
114 str.c_str(), static_cast<int>(str.length()),
-
115 NULL, 0) ;
-
116 if(needed_size <= 0) {
-
117 return false ;
+
97namespace fluent_tray
+
98{
+
99 static constexpr int MESSAGE_ID = WM_APP + FLUENT_TRAY_MESSAGE_ID_OFFSET ;
+
100
+
105 namespace util
+
106 {
+
+
114 bool string2wstring(const std::string& str, std::wstring& wstr) {
+
115 if(str.empty()) {
+
116 wstr.clear() ;
+
117 return true ;
118 }
119
-
120 wstr.resize(needed_size) ;
-
121 if(MultiByteToWideChar(
-
122 CP_UTF8, 0,
-
123 str.c_str(), static_cast<int>(str.length()),
-
124 &wstr[0], static_cast<int>(wstr.length())) <= 0) {
-
125 return false;
+
120 auto needed_size = MultiByteToWideChar(
+
121 CP_UTF8, 0,
+
122 str.c_str(), static_cast<int>(str.length()),
+
123 NULL, 0) ;
+
124 if(needed_size <= 0) {
+
125 return false ;
126 }
-
127 return true ;
-
128 }
+
127
+
128 wstr.resize(needed_size) ;
+
129 if(MultiByteToWideChar(
+
130 CP_UTF8, 0,
+
131 str.c_str(), static_cast<int>(str.length()),
+
132 &wstr[0], static_cast<int>(wstr.length())) <= 0) {
+
133 return false;
+
134 }
+
135 return true ;
+
136 }
-
129
-
-
137 bool wstring2string(const std::wstring& wstr, std::string& str) {
-
138 if(wstr.empty()) {
-
139 str.clear() ;
-
140 return true ;
-
141 }
-
142
-
143 auto needed_size = WideCharToMultiByte(
-
144 CP_UTF8, 0,
-
145 wstr.c_str(), static_cast<int>(wstr.length()),
-
146 NULL, 0,
-
147 NULL, NULL) ;
-
148 if(needed_size <= 0) {
-
149 return false ;
-
150 }
-
151
-
152 str.resize(needed_size) ;
-
153 if(WideCharToMultiByte(
-
154 CP_UTF8, 0,
-
155 wstr.c_str(), static_cast<int>(wstr.length()),
-
156 &str[0], static_cast<int>(str.size()),
-
157 NULL, NULL) <= 0) {
-
158 return false ;
-
159 }
-
160 return true ;
-
161 }
+
137
+
+
145 bool wstring2string(const std::wstring& wstr, std::string& str) {
+
146 if(wstr.empty()) {
+
147 str.clear() ;
+
148 return true ;
+
149 }
+
150
+
151 auto needed_size = WideCharToMultiByte(
+
152 CP_UTF8, 0,
+
153 wstr.c_str(), static_cast<int>(wstr.length()),
+
154 NULL, 0,
+
155 NULL, NULL) ;
+
156 if(needed_size <= 0) {
+
157 return false ;
+
158 }
+
159
+
160 str.resize(needed_size) ;
+
161 if(WideCharToMultiByte(
+
162 CP_UTF8, 0,
+
163 wstr.c_str(), static_cast<int>(wstr.length()),
+
164 &str[0], static_cast<int>(str.size()),
+
165 NULL, NULL) <= 0) {
+
166 return false ;
+
167 }
+
168 return true ;
+
169 }
-
162
-
-
168 inline constexpr std::size_t bit2mask(std::size_t bits) noexcept {
-
169 return (static_cast<std::size_t>(1) << bits) - 1 ;
-
170 }
+
170
+
+
176 inline constexpr std::size_t bit2mask(std::size_t bits) noexcept {
+
177 return (static_cast<std::size_t>(1) << bits) - 1 ;
+
178 }
-
171
-
176 template <typename Type>
-
-
177 inline constexpr int type2bit() noexcept {
-
178 return static_cast<int>(sizeof(Type) * CHAR_BIT) ;
-
179 }
+
179
+
184 template <typename Type>
+
+
185 inline constexpr int type2bit() noexcept {
+
186 return static_cast<int>(sizeof(Type) * CHAR_BIT) ;
+
187 }
-
180
-
189 template <typename InType, typename OutType>
-
-
190 inline void split_bits(InType input, OutType& upper, OutType& lower) noexcept {
-
191 constexpr auto bits = type2bit<OutType>() ;
-
192 static const auto lower_mask = util::bit2mask(bits) ;
-
193
-
194 upper = static_cast<OutType>(reinterpret_cast<std::size_t>(input) >> bits) ;
-
195 lower = static_cast<OutType>(reinterpret_cast<std::size_t>(input) & lower_mask) ;
-
196 }
+
188
+
197 template <typename InType, typename OutType>
+
+
198 inline void split_bits(InType input, OutType& upper, OutType& lower) noexcept {
+
199 constexpr auto bits = type2bit<OutType>() ;
+
200 static const auto lower_mask = util::bit2mask(bits) ;
+
201
+
202 upper = static_cast<OutType>(reinterpret_cast<std::size_t>(input) >> bits) ;
+
203 lower = static_cast<OutType>(reinterpret_cast<std::size_t>(input) & lower_mask) ;
+
204 }
-
197
-
205 template <typename InType, typename OutType>
-
- -
207 constexpr auto bits = type2bit<InType>() ;
-
208 static const auto lower_mask = util::bit2mask(bits) ;
-
209
-
210 auto out_upper = static_cast<std::size_t>(upper) << bits ;
-
211 auto out_lower = static_cast<std::size_t>(lower) & lower_mask ;
-
212 out = reinterpret_cast<OutType>(out_upper | out_lower) ;
-
213 }
+
205
+
213 template <typename InType, typename OutType>
+
+ +
215 constexpr auto bits = type2bit<InType>() ;
+
216 static const auto lower_mask = util::bit2mask(bits) ;
+
217
+
218 auto out_upper = static_cast<std::size_t>(upper) << bits ;
+
219 auto out_lower = static_cast<std::size_t>(lower) & lower_mask ;
+
220 out = reinterpret_cast<OutType>(out_upper | out_lower) ;
+
221 }
-
-
219 inline unsigned char rgb2gray(const COLORREF& rgb) {
-
220 auto r = GetRValue(rgb) ;
-
221 auto g = GetGValue(rgb) ;
-
222 auto b = GetBValue(rgb) ;
-
223 return static_cast<unsigned char>(0.2126 * r + 0.7152 * g + 0.0722 * b) ;
-
224 }
+
+
227 inline unsigned char rgb2gray(const COLORREF& rgb) {
+
228 auto r = GetRValue(rgb) ;
+
229 auto g = GetGValue(rgb) ;
+
230 auto b = GetBValue(rgb) ;
+
231 return static_cast<unsigned char>(0.2126 * r + 0.7152 * g + 0.0722 * b) ;
+
232 }
-
225
-
-
231 inline bool exists(const std::wstring& path) {
-
232 struct _stat buffer ;
-
233 return _wstat(path.c_str(), &buffer) == 0 ;
-
234 }
+
233
+
+
239 inline bool exists(const std::wstring& path) {
+
240 struct _stat buffer ;
+
241 return _wstat(path.c_str(), &buffer) == 0 ;
+
242 }
-
235 }
-
236
-
-
240 enum class TrayStatus : unsigned char
-
241 {
-
243 RUNNING,
+
243 }
244
- -
247
-
249 FAILED,
-
250
-
252 STOPPED,
-
253 } ;
+
+
248 enum class TrayStatus : unsigned char
+
249 {
+
251 RUNNING,
+
252
+ +
255
+
257 FAILED,
+
258
+
260 STOPPED,
+
261 } ;
-
254
-
- -
259 private:
-
260 std::wstring label_ ;
-
261 HICON hicon_ ;
262
-
263 bool toggleable_ ;
-
264 bool checked_ ;
-
265 std::wstring checkmark_ ;
-
266
-
267 HWND hwnd_ ;
-
268 HMENU hmenu_ ;
-
269
-
270 bool under_line_ ;
-
271
-
272 COLORREF text_color_ ;
-
273 COLORREF back_color_ ;
-
274 COLORREF border_color_ ;
-
275 HBRUSH back_brush_ ;
-
276
-
277 std::function<bool(void)> callback_ ;
-
278 std::function<bool(void)> unchecked_callback_ ;
+
+ +
267 private:
+
268 std::wstring label_ ;
+
269 HICON hicon_ ;
+
270
+
271 bool toggleable_ ;
+
272 bool checked_ ;
+
273 std::wstring checkmark_ ;
+
274
+
275 HWND hwnd_ ;
+
276 HMENU hmenu_ ;
+
277
+
278 bool under_line_ ;
279
-
280 public:
-
-
288 explicit FluentMenu(
-
289 bool toggleable=false,
-
290 const std::function<bool(void)>& callback=[] {return true ;},
-
291 const std::function<bool(void)>& unchecked_callback=[] {return true ;})
-
292 : label_(),
-
293 hicon_(NULL),
-
294 toggleable_(toggleable),
-
295 checked_(false),
-
296 checkmark_(),
-
297 hwnd_(NULL),
-
298 hmenu_(NULL),
-
299 under_line_(false),
-
300 text_color_(RGB(0, 0, 0)),
-
301 back_color_(RGB(255, 255, 255)),
-
302 border_color_(RGB(128, 128, 128)),
-
303 back_brush_(NULL),
-
304 callback_(callback),
-
305 unchecked_callback_(unchecked_callback)
-
306 {}
+
280 COLORREF text_color_ ;
+
281 COLORREF back_color_ ;
+
282 COLORREF border_color_ ;
+
283 HBRUSH back_brush_ ;
+
284
+
285 std::function<bool(void)> callback_ ;
+
286 std::function<bool(void)> unchecked_callback_ ;
+
287
+
288 public:
+
+
296 explicit FluentMenu(
+
297 bool toggleable=false,
+
298 const std::function<bool(void)>& callback=[] {return true ;},
+
299 const std::function<bool(void)>& unchecked_callback=[] {return true ;})
+
300 : label_(),
+
301 hicon_(NULL),
+
302 toggleable_(toggleable),
+
303 checked_(false),
+
304 checkmark_(),
+
305 hwnd_(NULL),
+
306 hmenu_(NULL),
+
307 under_line_(false),
+
308 text_color_(RGB(0, 0, 0)),
+
309 back_color_(RGB(255, 255, 255)),
+
310 border_color_(RGB(128, 128, 128)),
+
311 back_brush_(NULL),
+
312 callback_(callback),
+
313 unchecked_callback_(unchecked_callback)
+
314 {}
-
307
-
308 FluentMenu(const FluentMenu&) = default ;
-
309 FluentMenu& operator=(const FluentMenu&) = default ;
-
310
-
311 FluentMenu(FluentMenu&&) = default ;
- -
313
-
-
314 ~FluentMenu() noexcept {
-
315 if(back_brush_) {
-
316 DeleteObject(back_brush_) ;
-
317 }
-
318 }
+
315
+
316 FluentMenu(const FluentMenu&) = default ;
+
317 FluentMenu& operator=(const FluentMenu&) = default ;
+
318
+
319 FluentMenu(FluentMenu&&) = default ;
+ +
321
+
+
322 ~FluentMenu() noexcept {
+
323 if(back_brush_) {
+
324 DeleteObject(back_brush_) ;
+
325 }
+
326 }
-
319
-
- -
331 HINSTANCE hinstance,
-
332 HWND parent_hwnd,
-
333 std::size_t id,
-
334 const std::string& label_text="",
-
335 const std::string& icon_path="",
-
336 const std::string& checkmark="✓") {
-
337
-
338 // Convert strings to the wide-strings
-
339 if(!util::string2wstring(label_text, label_)) {
-
340 return false ;
-
341 }
-
342 if(!util::string2wstring(checkmark, checkmark_)) {
-
343 return false ;
-
344 }
+
327
+
+ +
339 HINSTANCE hinstance,
+
340 HWND parent_hwnd,
+
341 std::size_t id,
+
342 const std::string& label_text="",
+
343 const std::string& icon_path="",
+
344 const std::string& checkmark="✓") {
345
-
346 auto style = WS_CHILD | WS_VISIBLE | BS_FLAT | BS_LEFT | BS_OWNERDRAW ;
-
347
-
348 hmenu_ = reinterpret_cast<HMENU>(id) ;
-
349 hwnd_ = CreateWindowW(
-
350 TEXT("BUTTON"), label_.c_str(), style,
-
351 0, 0, 100, 100,
-
352 parent_hwnd, hmenu_,
-
353 hinstance, NULL) ;
-
354 if(!hwnd_) {
-
355 return false ;
-
356 }
-
357
-
358 // Hide dash lines when selecting.
-
359 SendMessageW(
-
360 hwnd_, WM_CHANGEUISTATE,
-
361 WPARAM(MAKELONG(UIS_SET, UISF_HIDEFOCUS)), 0) ;
-
362
-
363 if(!icon_path.empty()) {
-
364 std::wstring icon_path_wide ;
-
365 if(!util::string2wstring(icon_path, icon_path_wide)) {
-
366 return false ;
-
367 }
-
368
-
369 if(!util::exists(icon_path_wide)) {
-
370 return false ;
-
371 }
-
372
-
373 hicon_ = static_cast<HICON>(LoadImageW(
-
374 NULL, icon_path_wide.c_str(),
-
375 IMAGE_ICON, 0, 0, LR_LOADFROMFILE)) ;
-
376 if(!hicon_) {
-
377 return false ;
-
378 }
-
379 }
+
346 // Convert strings to the wide-strings
+
347 if(!util::string2wstring(label_text, label_)) {
+
348 return false ;
+
349 }
+
350 if(!util::string2wstring(checkmark, checkmark_)) {
+
351 return false ;
+
352 }
+
353
+
354 auto style = WS_CHILD | WS_VISIBLE | BS_FLAT | BS_LEFT | BS_OWNERDRAW ;
+
355
+
356 hmenu_ = reinterpret_cast<HMENU>(id) ;
+
357 hwnd_ = CreateWindowW(
+
358 TEXT("BUTTON"), label_.c_str(), style,
+
359 0, 0, 100, 100,
+
360 parent_hwnd, hmenu_,
+
361 hinstance, NULL) ;
+
362 if(!hwnd_) {
+
363 return false ;
+
364 }
+
365
+
366 // Hide dash lines when selecting.
+
367 SendMessageW(
+
368 hwnd_, WM_CHANGEUISTATE,
+
369 WPARAM(MAKELONG(UIS_SET, UISF_HIDEFOCUS)), 0) ;
+
370
+
371 if(!icon_path.empty()) {
+
372 std::wstring icon_path_wide ;
+
373 if(!util::string2wstring(icon_path, icon_path_wide)) {
+
374 return false ;
+
375 }
+
376
+
377 if(!util::exists(icon_path_wide)) {
+
378 return false ;
+
379 }
380
-
381 return true ;
-
382 }
+
381 hicon_ = static_cast<HICON>(LoadImageW(
+
382 NULL, icon_path_wide.c_str(),
+
383 IMAGE_ICON, 0, 0, LR_LOADFROMFILE)) ;
+
384 if(!hicon_) {
+
385 return false ;
+
386 }
+
387 }
+
388
+
389 return true ;
+
390 }
-
383
-
- -
390 if(toggleable_) {
-
391 checked_ = !checked_ ;
-
392 if(!checked_) {
-
393 return unchecked_callback_() ;
-
394 }
-
395 }
-
396 return callback_() ;
-
397 }
+
391
+
+ +
398 if(toggleable_) {
+
399 checked_ = !checked_ ;
+
400 if(!checked_) {
+
401 return unchecked_callback_() ;
+
402 }
+
403 }
+
404 return callback_() ;
+
405 }
-
398
-
-
403 bool is_mouse_over() const {
-
404 POINT pos ;
-
405 if(!GetCursorPos(&pos)) {
-
406 return false ;
-
407 }
-
408 auto detected_hwnd = WindowFromPoint(pos) ;
-
409 if(!detected_hwnd) {
-
410 return false ;
-
411 }
-
412 return detected_hwnd == hwnd_ ;
-
413 }
+
406
+
+
411 bool is_mouse_over() const {
+
412 POINT pos ;
+
413 if(!GetCursorPos(&pos)) {
+
414 return false ;
+
415 }
+
416 auto detected_hwnd = WindowFromPoint(pos) ;
+
417 if(!detected_hwnd) {
+
418 return false ;
+
419 }
+
420 return detected_hwnd == hwnd_ ;
+
421 }
-
414
-
-
419 void check() noexcept {
-
420 if(toggleable_) {
-
421 checked_ = true ;
-
422 }
-
423 }
+
422
+
+
427 void check() noexcept {
+
428 if(toggleable_) {
+
429 checked_ = true ;
+
430 }
+
431 }
-
424
-
-
429 void uncheck() noexcept {
-
430 if(toggleable_) {
-
431 checked_ = false ;
-
432 }
-
433 }
+
432
+
+
437 void uncheck() noexcept {
+
438 if(toggleable_) {
+
439 checked_ = false ;
+
440 }
+
441 }
-
434
-
-
439 bool is_checked() const noexcept {
-
440 if(!toggleable_) {
-
441 return false ;
-
442 }
-
443 return checked_ ;
-
444 }
-
-
445
-
-
450 bool is_toggleable() const noexcept {
-
451 return toggleable_ ;
+
442
+
+
447 bool is_checked() const noexcept {
+
448 if(!toggleable_) {
+
449 return false ;
+
450 }
+
451 return checked_ ;
452 }
453
-
458 HWND window_handle() const noexcept {
-
459 return hwnd_ ;
+
458 bool is_toggleable() const noexcept {
+
459 return toggleable_ ;
460 }
461
-
466 HMENU menu_handle() const noexcept {
-
467 return hmenu_ ;
+
466 HWND window_handle() const noexcept {
+
467 return hwnd_ ;
468 }
469
-
474 std::size_t id() const noexcept {
-
475 return reinterpret_cast<std::size_t>(hmenu_) ;
+
474 HMENU menu_handle() const noexcept {
+
475 return hmenu_ ;
476 }
+
477
-
482 bool get_label(std::string& str) const {
-
483 return util::wstring2string(label_, str) ;
+
482 std::size_t id() const noexcept {
+
483 return reinterpret_cast<std::size_t>(hmenu_) ;
484 }
-
485
-
-
489 void show_separator_line() noexcept {
-
490 under_line_ = true ;
-
491 }
+
+
490 bool get_label(std::string& str) const {
+
491 return util::wstring2string(label_, str) ;
+
492 }
+
+
493
+
+
497 void show_separator_line() noexcept {
+
498 under_line_ = true ;
+
499 }
-
492
-
-
496 void hide_separator_line() noexcept {
-
497 under_line_ = false ;
-
498 }
+
500
+
+
504 void hide_separator_line() noexcept {
+
505 under_line_ = false ;
+
506 }
-
499
-
- -
509 const COLORREF& text_color=CLR_INVALID,
-
510 const COLORREF& back_color=CLR_INVALID,
-
511 const COLORREF& border_color=CLR_INVALID) noexcept {
-
512 if(text_color != CLR_INVALID) {
-
513 text_color_ = text_color ;
-
514 }
-
515 if(back_color != CLR_INVALID) {
-
516 back_color_ = back_color ;
-
517 }
-
518 if(border_color != CLR_INVALID) {
-
519 border_color_ = border_color ;
-
520 }
-
521
-
522 // Create brush handle to draw a background of window.
-
523 if(back_brush_) {
-
524 // Release old handle.
-
525 if(!DeleteObject(back_brush_)) {
-
526 return false ;
-
527 }
+
507
+
+ +
517 const COLORREF& text_color=CLR_INVALID,
+
518 const COLORREF& back_color=CLR_INVALID,
+
519 const COLORREF& border_color=CLR_INVALID) noexcept {
+
520 if(text_color != CLR_INVALID) {
+
521 text_color_ = text_color ;
+
522 }
+
523 if(back_color != CLR_INVALID) {
+
524 back_color_ = back_color ;
+
525 }
+
526 if(border_color != CLR_INVALID) {
+
527 border_color_ = border_color ;
528 }
-
529 back_brush_ = CreateSolidBrush(back_color_) ;
-
530 if(back_brush_ == NULL) {
-
531 return false ;
-
532 }
-
533
-
534 return true ;
-
535 }
+
529
+
530 // Create brush handle to draw a background of window.
+
531 if(back_brush_) {
+
532 // Release old handle.
+
533 if(!DeleteObject(back_brush_)) {
+
534 return false ;
+
535 }
+
536 }
+
537 back_brush_ = CreateSolidBrush(back_color_) ;
+
538 if(back_brush_ == NULL) {
+
539 return false ;
+
540 }
+
541
+
542 return true ;
+
543 }
-
536
-
-
544 bool draw_menu(LPDRAWITEMSTRUCT info, HFONT font) const {
-
545 if(SetTextColor(info->hDC, text_color_) == CLR_INVALID) {
-
546 return false ;
-
547 }
-
548
-
549 if(SetBkColor(info->hDC, back_color_) == CLR_INVALID) {
-
550 return false ;
-
551 }
-
552
-
553 if(font) {
-
554 if(!SelectObject(info->hDC, font)) {
-
555 return false ;
-
556 }
-
557 }
-
558
-
559 LONG checkmark_size, label_height, icon_size, margin ;
-
560 if(!calculate_layouts(
-
561 info->hDC,
-
562 checkmark_size, label_height, icon_size, margin)) {
-
563 return false ;
-
564 }
-
565
-
566 auto& rect = info->rcItem ;
-
567
-
568 auto y_center = rect.top + (rect.bottom - rect.top) / 2 ;
-
569 auto x = rect.left + margin ;
-
570
-
571 if(toggleable_ && checked_) {
-
572 if(!TextOutW(
-
573 info->hDC, x, y_center - label_height / 2, checkmark_.c_str(),
-
574 static_cast<int>(checkmark_.length()))) {
-
575 return false ;
-
576 }
-
577 }
-
578 x += checkmark_size + margin ;
-
579
-
580 if(hicon_) {
-
581 if(!DrawIconEx(
-
582 info->hDC, x, y_center - SM_CYICON / 2, hicon_,
-
583 icon_size, icon_size, 0, NULL, DI_NORMAL)) {
-
584 return false ;
-
585 }
-
586 }
-
587 x += icon_size + margin ;
-
588
-
589 if(!TextOutW(
-
590 info->hDC, x, y_center - label_height / 2, label_.c_str(),
-
591 static_cast<int>(label_.length()))) {
-
592 return false ;
-
593 }
-
594
-
595 if(under_line_) {
-
596 auto original_obj = SelectObject(info->hDC, GetStockObject(DC_PEN)) ;
-
597 if(SetDCPenColor(info->hDC, border_color_) == CLR_INVALID) {
-
598 return false ;
-
599 }
-
600
-
601 auto lx = info->rcItem.left ;
-
602 auto ly = info->rcItem.bottom - 1 ;
-
603 auto rx = info->rcItem.right ;
-
604 auto ry = ly + 1 ;
-
605 if(!Rectangle(info->hDC, lx, ly, rx, ry)) {
+
544
+
+
552 bool draw_menu(LPDRAWITEMSTRUCT info, HFONT font) const {
+
553 if(SetTextColor(info->hDC, text_color_) == CLR_INVALID) {
+
554 return false ;
+
555 }
+
556
+
557 if(SetBkColor(info->hDC, back_color_) == CLR_INVALID) {
+
558 return false ;
+
559 }
+
560
+
561 if(font) {
+
562 if(!SelectObject(info->hDC, font)) {
+
563 return false ;
+
564 }
+
565 }
+
566
+
567 LONG checkmark_size, label_height, icon_size, margin ;
+
568 if(!calculate_layouts(
+
569 info->hDC,
+
570 checkmark_size, label_height, icon_size, margin)) {
+
571 return false ;
+
572 }
+
573
+
574 auto& rect = info->rcItem ;
+
575
+
576 auto y_center = rect.top + (rect.bottom - rect.top) / 2 ;
+
577 auto x = rect.left + margin ;
+
578
+
579 if(toggleable_ && checked_) {
+
580 if(!TextOutW(
+
581 info->hDC, x, y_center - label_height / 2, checkmark_.c_str(),
+
582 static_cast<int>(checkmark_.length()))) {
+
583 return false ;
+
584 }
+
585 }
+
586 x += checkmark_size + margin ;
+
587
+
588 if(hicon_) {
+
589 if(!DrawIconEx(
+
590 info->hDC, x, y_center - SM_CYICON / 2, hicon_,
+
591 icon_size, icon_size, 0, NULL, DI_NORMAL)) {
+
592 return false ;
+
593 }
+
594 }
+
595 x += icon_size + margin ;
+
596
+
597 if(!TextOutW(
+
598 info->hDC, x, y_center - label_height / 2, label_.c_str(),
+
599 static_cast<int>(label_.length()))) {
+
600 return false ;
+
601 }
+
602
+
603 if(under_line_) {
+
604 auto original_obj = SelectObject(info->hDC, GetStockObject(DC_PEN)) ;
+
605 if(SetDCPenColor(info->hDC, border_color_) == CLR_INVALID) {
606 return false ;
607 }
608
-
609 if(!SelectObject(info->hDC, original_obj)) {
-
610 return false ;
-
611 }
-
612 }
-
613
-
614 return true ;
-
615 }
-
-
-
621 HBRUSH background_brush() const noexcept {
-
622 return back_brush_ ;
+
609 auto lx = info->rcItem.left ;
+
610 auto ly = info->rcItem.bottom - 1 ;
+
611 auto rx = info->rcItem.right ;
+
612 auto ry = ly + 1 ;
+
613 if(!Rectangle(info->hDC, lx, ly, rx, ry)) {
+
614 return false ;
+
615 }
+
616
+
617 if(!SelectObject(info->hDC, original_obj)) {
+
618 return false ;
+
619 }
+
620 }
+
621
+
622 return true ;
623 }
-
-
630 bool calculate_required_dims(HFONT font, SIZE& size) const {
-
631 auto hdc = GetDC(hwnd_) ;
-
632 if(font) {
-
633 if(!SelectObject(hdc, font)) {
-
634 return false ;
-
635 }
-
636 }
-
637
-
638 if(!GetTextExtentPoint32W(
-
639 hdc, label_.c_str(),
-
640 static_cast<int>(label_.length()), &size)) {
-
641 return false ;
-
642 }
-
643
-
644 LONG checkmark_size, label_height, icon_size, margin ;
-
645 if(!calculate_layouts(
-
646 hdc, checkmark_size, label_height, icon_size, margin)) {
-
647 return false ;
-
648 }
-
649
-
650 size.cx += margin + checkmark_size + margin + icon_size + margin ;
+
+
629 HBRUSH background_brush() const noexcept {
+
630 return back_brush_ ;
+
631 }
+
+
+
638 bool calculate_required_dims(HFONT font, SIZE& size) const {
+
639 auto hdc = GetDC(hwnd_) ;
+
640 if(font) {
+
641 if(!SelectObject(hdc, font)) {
+
642 return false ;
+
643 }
+
644 }
+
645
+
646 if(!GetTextExtentPoint32W(
+
647 hdc, label_.c_str(),
+
648 static_cast<int>(label_.length()), &size)) {
+
649 return false ;
+
650 }
651
-
652 return true ;
-
653 }
+
652 LONG checkmark_size, label_height, icon_size, margin ;
+
653 if(!calculate_layouts(
+
654 hdc, checkmark_size, label_height, icon_size, margin)) {
+
655 return false ;
+
656 }
+
657
+
658 size.cx += margin + checkmark_size + margin + icon_size + margin ;
+
659
+
660 return true ;
+
661 }
-
654
-
655
-
656 private:
-
657 bool calculate_layouts(
-
658 HDC hdc,
-
659 LONG& checkmark_size,
-
660 LONG& label_height,
-
661 LONG& icon_size,
-
662 LONG& margin) const {
-
663 SIZE size ;
-
664 if(!GetTextExtentPoint32W(hdc, L" ", 1, &size)) {
-
665 return false ;
-
666 }
-
667 checkmark_size = size.cy ;
-
668 margin = size.cy / 2 ;
-
669 label_height = size.cy ;
-
670 icon_size = 4 * label_height / 5 ;
-
671 return true ;
-
672 }
-
673
-
674 } ;
+
662
+
663
+
664 private:
+
665 bool calculate_layouts(
+
666 HDC hdc,
+
667 LONG& checkmark_size,
+
668 LONG& label_height,
+
669 LONG& icon_size,
+
670 LONG& margin) const {
+
671 SIZE size ;
+
672 if(!GetTextExtentPoint32W(hdc, L" ", 1, &size)) {
+
673 return false ;
+
674 }
+
675 checkmark_size = size.cy ;
+
676 margin = size.cy / 2 ;
+
677 label_height = size.cy ;
+
678 icon_size = 4 * label_height / 5 ;
+
679 return true ;
+
680 }
+
681
+
682 } ;
-
675
-
676
-
- -
681 private:
-
682 std::vector<FluentMenu> menus_ ;
-
683 std::vector<bool> mouse_is_over_ ;
+
683
684
-
685 std::wstring app_name_ ;
-
686
-
687 HINSTANCE hinstance_ ;
-
688 HWND hwnd_ ;
-
689 bool visible_ ;
-
690 NOTIFYICONDATAW icon_data_ ;
-
691
-
692 TrayStatus status_ ;
-
693
-
694 std::size_t next_menu_id_ ;
-
695
-
696 LONG menu_x_margin_ ;
-
697 LONG menu_y_margin_ ;
-
698
-
699 LONG menu_x_pad_ ;
-
700 LONG menu_y_pad_ ;
+
+ +
689 private:
+
690 std::vector<FluentMenu> menus_ ;
+
691 std::vector<bool> mouse_is_over_ ;
+
692
+
693 std::wstring app_name_ ;
+
694
+
695 HINSTANCE hinstance_ ;
+
696 HWND hwnd_ ;
+
697 bool visible_ ;
+
698 NOTIFYICONDATAW icon_data_ ;
+
699
+
700 TrayStatus status_ ;
701
-
702 COLORREF text_color_ ;
-
703 COLORREF back_color_ ;
-
704 COLORREF ash_color_ ;
-
705 HBRUSH back_brush_ ;
+
702 std::size_t next_menu_id_ ;
+
703
+
704 LONG menu_x_margin_ ;
+
705 LONG menu_y_margin_ ;
706
-
707 LONG menu_font_size_ ;
-
708 HFONT font_ ;
+
707 LONG menu_x_pad_ ;
+
708 LONG menu_y_pad_ ;
709
-
710 public:
-
-
714 explicit FluentTray()
-
715 : menus_(),
-
716 mouse_is_over_(),
-
717 app_name_(),
-
718 hinstance_(GetModuleHandle(NULL)),
-
719 hwnd_(NULL),
-
720 visible_(false),
-
721 icon_data_(),
-
722 status_(TrayStatus::STOPPED),
-
723 next_menu_id_(1),
-
724 menu_x_margin_(5),
-
725 menu_y_margin_(5),
-
726 menu_x_pad_(5),
-
727 menu_y_pad_(5),
-
728 text_color_(RGB(30, 30, 30)),
-
729 back_color_(RGB(200, 200, 200)),
-
730 ash_color_(RGB(100, 100, 100)),
-
731 back_brush_(NULL),
-
732 menu_font_size_(0),
-
733 font_(NULL)
-
734 {}
+
710 COLORREF text_color_ ;
+
711 COLORREF back_color_ ;
+
712 COLORREF ash_color_ ;
+
713 HBRUSH back_brush_ ;
+
714
+
715 LONG menu_font_size_ ;
+
716 HFONT font_ ;
+
717
+
718 public:
+
+
722 explicit FluentTray()
+
723 : menus_(),
+
724 mouse_is_over_(),
+
725 app_name_(),
+
726 hinstance_(GetModuleHandle(NULL)),
+
727 hwnd_(NULL),
+
728 visible_(false),
+
729 icon_data_(),
+
730 status_(TrayStatus::STOPPED),
+
731 next_menu_id_(1),
+
732 menu_x_margin_(5),
+
733 menu_y_margin_(5),
+
734 menu_x_pad_(5),
+
735 menu_y_pad_(5),
+
736 text_color_(RGB(30, 30, 30)),
+
737 back_color_(RGB(200, 200, 200)),
+
738 ash_color_(RGB(100, 100, 100)),
+
739 back_brush_(NULL),
+
740 menu_font_size_(0),
+
741 font_(NULL)
+
742 {}
-
735
-
736 // Copy
-
737 FluentTray(const FluentTray&) = delete ;
-
738 FluentTray& operator=(const FluentTray&) = delete ;
-
739
-
740 // Move
-
741 FluentTray(FluentTray&&) = default ;
-
743
-
-
744 virtual ~FluentTray() noexcept {
-
745 if(font_ != NULL) {
-
746 DeleteObject(font_) ;
-
747 }
-
748 if(back_brush_ != NULL) {
-
749 DeleteObject(back_brush_) ;
-
750 }
-
751 }
+
744 // Copy
+
745 FluentTray(const FluentTray&) = delete ;
+
746 FluentTray& operator=(const FluentTray&) = delete ;
+
747
+
748 // Move
+
749 FluentTray(FluentTray&&) = default ;
+ +
751
+
+
752 virtual ~FluentTray() noexcept {
+
753 if(font_ != NULL) {
+
754 DeleteObject(font_) ;
+
755 }
+
756 if(back_brush_ != NULL) {
+
757 DeleteObject(back_brush_) ;
+
758 }
+
759 }
-
752
-
- -
766 const std::string& app_name,
-
767 const std::string& icon_path="",
-
768 LONG menu_x_margin=5,
-
769 LONG menu_y_margin=5,
-
770 LONG menu_x_pad=5,
-
771 LONG menu_y_pad=5,
-
772 unsigned char opacity=255,
-
773 bool round_corner=true) {
-
774 if(!util::string2wstring(app_name, app_name_)) {
-
775 return false ;
-
776 }
-
777
-
778 menu_x_margin_ = menu_x_margin ;
-
779 menu_y_margin_ = menu_y_margin ;
-
780 menu_x_pad_ = menu_x_pad ;
-
781 menu_y_pad_ = menu_y_pad ;
-
782
-
783 WNDCLASSW winc ;
-
784 winc.style = CS_HREDRAW | CS_VREDRAW ;
-
785 winc.lpfnWndProc = &FluentTray::callback ;
-
786 winc.cbClsExtra = 0 ;
-
787 winc.cbWndExtra = sizeof(LONG) * 2 ; // To store two-part address.
-
788 winc.hInstance = hinstance_ ;
-
789 winc.hIcon = LoadIcon(NULL, IDI_APPLICATION) ;
-
790 winc.hCursor = LoadCursor(NULL, IDC_ARROW) ;
-
791 winc.hbrBackground = GetSysColorBrush(COLOR_WINDOW) ;
-
792 winc.lpszMenuName = NULL ;
-
793 winc.lpszClassName = app_name_.c_str() ;
-
794
-
795 if(!RegisterClassW(&winc)) {
-
796 return false ;
-
797 }
-
798
-
799 hwnd_ = CreateWindowExW(
-
800 WS_EX_TOOLWINDOW | WS_EX_LAYERED,
-
801 app_name_.c_str(),
-
802 app_name_.c_str(),
-
803 WS_POPUPWINDOW,
-
804 0, 0, 100, 100,
-
805 NULL, NULL,
-
806 hinstance_, NULL
-
807 ) ;
-
808 if(!hwnd_) {
-
809 return false ;
-
810 }
-
811
-
812 // To access the this pointer inside the callback function,
-
813 // the address divide into the two part address.
-
814 LONG upper_addr, lower_addr ;
-
815 util::split_bits(this, upper_addr, lower_addr) ;
-
816
-
817 SetLastError(0) ;
-
818 if(!SetWindowLongW(hwnd_, 0, upper_addr) && GetLastError() != 0) {
-
819 return false ;
-
820 }
-
821 SetLastError(0) ;
-
822 if(!SetWindowLongW(hwnd_, sizeof(LONG), lower_addr) && GetLastError() != 0) {
-
823 return false ;
-
824 }
-
825
-
826 if(!SetLayeredWindowAttributes(hwnd_, 0, opacity, LWA_ALPHA)) {
+
760
+
+ +
774 const std::string& app_name,
+
775 const std::string& icon_path="",
+
776 LONG menu_x_margin=5,
+
777 LONG menu_y_margin=5,
+
778 LONG menu_x_pad=5,
+
779 LONG menu_y_pad=5,
+
780 unsigned char opacity=255,
+
781 bool round_corner=true) {
+
782 if(!util::string2wstring(app_name, app_name_)) {
+
783 return false ;
+
784 }
+
785
+
786 menu_x_margin_ = menu_x_margin ;
+
787 menu_y_margin_ = menu_y_margin ;
+
788 menu_x_pad_ = menu_x_pad ;
+
789 menu_y_pad_ = menu_y_pad ;
+
790
+
791 WNDCLASSW winc ;
+
792 winc.style = CS_HREDRAW | CS_VREDRAW ;
+
793 winc.lpfnWndProc = &FluentTray::callback ;
+
794 winc.cbClsExtra = 0 ;
+
795 winc.cbWndExtra = sizeof(LONG) * 2 ; // To store two-part address.
+
796 winc.hInstance = hinstance_ ;
+
797 winc.hIcon = LoadIcon(NULL, IDI_APPLICATION) ;
+
798 winc.hCursor = LoadCursor(NULL, IDC_ARROW) ;
+
799 winc.hbrBackground = GetSysColorBrush(COLOR_WINDOW) ;
+
800 winc.lpszMenuName = NULL ;
+
801 winc.lpszClassName = app_name_.c_str() ;
+
802
+
803 if(!RegisterClassW(&winc)) {
+
804 return false ;
+
805 }
+
806
+
807 hwnd_ = CreateWindowExW(
+
808 WS_EX_TOOLWINDOW | WS_EX_LAYERED,
+
809 app_name_.c_str(),
+
810 app_name_.c_str(),
+
811 WS_POPUPWINDOW,
+
812 0, 0, 100, 100,
+
813 NULL, NULL,
+
814 hinstance_, NULL
+
815 ) ;
+
816 if(!hwnd_) {
+
817 return false ;
+
818 }
+
819
+
820 // To access the this pointer inside the callback function,
+
821 // the address divide into the two part address.
+
822 LONG upper_addr, lower_addr ;
+
823 util::split_bits(this, upper_addr, lower_addr) ;
+
824
+
825 SetLastError(0) ;
+
826 if(!SetWindowLongW(hwnd_, 0, upper_addr) && GetLastError() != 0) {
827 return false ;
828 }
-
829
-
830 // Set rounded window for Windows 11 only.
-
831 if(round_corner) {
-
832#if defined(_MSC_VER) && _MSC_VER >= 1500
-
833 using RtlGetVersionType = NTSTATUS (WINAPI*)(PRTL_OSVERSIONINFOW) ;
-
834 const auto hmodule = LoadLibraryW(L"ntdll.dll") ;
-
835 if(!hmodule) {
-
836 return false ;
-
837 }
-
838
-
839 // cast to void* once to avoid warnings about type conversion.
-
840 const auto RtlGetVersion = reinterpret_cast<RtlGetVersionType>(
-
841 reinterpret_cast<void*>(GetProcAddress(hmodule, "RtlGetVersion"))) ;
-
842 if(!RtlGetVersion) {
-
843 FreeLibrary(hmodule) ;
+
829 SetLastError(0) ;
+
830 if(!SetWindowLongW(hwnd_, sizeof(LONG), lower_addr) && GetLastError() != 0) {
+
831 return false ;
+
832 }
+
833
+
834 if(!SetLayeredWindowAttributes(hwnd_, 0, opacity, LWA_ALPHA)) {
+
835 return false ;
+
836 }
+
837
+
838 // Set rounded window for Windows 11 only.
+
839 if(round_corner) {
+
840#if defined(_MSC_VER) && _MSC_VER >= 1500
+
841 using RtlGetVersionType = NTSTATUS (WINAPI*)(PRTL_OSVERSIONINFOW) ;
+
842 const auto hmodule = LoadLibraryW(L"ntdll.dll") ;
+
843 if(!hmodule) {
844 return false ;
845 }
846
-
847 OSVERSIONINFOW vinfo ;
-
848 vinfo.dwOSVersionInfoSize = sizeof(decltype(vinfo)) ;
-
849 auto result = RtlGetVersion(&vinfo) ;
-
850 if(!FreeLibrary(hmodule)) {
-
851 return false ;
-
852 }
-
853
-
854 if(result != STATUS_SUCCESS) {
-
855 return false ;
-
856 }
-
857
-
858 // Check if the OS is Windows11
-
859 if(vinfo.dwBuildNumber >= 22000) {
-
860 auto pref = DWMWCP_ROUND ;
-
861 if(DwmSetWindowAttribute(
-
862 hwnd_,
-
863 DWMWA_WINDOW_CORNER_PREFERENCE,
-
864 &pref, sizeof(pref)) != S_OK) {
-
865 return false ;
-
866 }
-
867 }
-
868#endif // defined(_MSC_VER) && _MSC_VER >= 1500
-
869 }
-
870
-
871 if(!change_icon(icon_path)) {
-
872 return false ;
-
873 }
-
874
-
875 if(!set_font()) {
-
876 return false ;
+
847 // cast to void* once to avoid warnings about type conversion.
+
848 const auto RtlGetVersion = reinterpret_cast<RtlGetVersionType>(
+
849 reinterpret_cast<void*>(GetProcAddress(hmodule, "RtlGetVersion"))) ;
+
850 if(!RtlGetVersion) {
+
851 FreeLibrary(hmodule) ;
+
852 return false ;
+
853 }
+
854
+
855 OSVERSIONINFOW vinfo ;
+
856 vinfo.dwOSVersionInfoSize = sizeof(decltype(vinfo)) ;
+
857 auto result = RtlGetVersion(&vinfo) ;
+
858 if(!FreeLibrary(hmodule)) {
+
859 return false ;
+
860 }
+
861
+
862 if(result != STATUS_SUCCESS) {
+
863 return false ;
+
864 }
+
865
+
866 // Check if the OS is Windows11
+
867 if(vinfo.dwBuildNumber >= 22000) {
+
868 auto pref = DWMWCP_ROUND ;
+
869 if(DwmSetWindowAttribute(
+
870 hwnd_,
+
871 DWMWA_WINDOW_CORNER_PREFERENCE,
+
872 &pref, sizeof(pref)) != S_OK) {
+
873 return false ;
+
874 }
+
875 }
+
876#endif // defined(_MSC_VER) && _MSC_VER >= 1500
877 }
878
-
879 if(!set_color()) {
+
879 if(!change_icon(icon_path)) {
880 return false ;
881 }
882
-
883 status_ = TrayStatus::RUNNING ;
-
884
-
885 return true ;
-
886 }
+
883 if(!set_font()) {
+
884 return false ;
+
885 }
+
886
+
887 if(!set_color()) {
+
888 return false ;
+
889 }
+
890
+
891 status_ = TrayStatus::RUNNING ;
+
892
+
893 return true ;
+
894 }
-
887
-
- -
899 const std::string& label_text="",
-
900 const std::string& icon_path="",
-
901 bool toggleable=false,
-
902 const std::string& checkmark="✓",
-
903 const std::function<bool(void)>& callback=[] {return true ;},
-
904 const std::function<bool(void)>& unchecked_callback=[] {return true ;}) {
-
905 FluentMenu menu(toggleable, callback, unchecked_callback) ;
-
906 if(!menu.create_menu(
-
907 hinstance_, hwnd_, next_menu_id_,
-
908 label_text, icon_path, checkmark)) {
-
909 return false ;
-
910 }
-
911
-
912 menus_.push_back(std::move(menu)) ;
-
913 mouse_is_over_.push_back(false) ;
-
914 next_menu_id_ ++ ;
-
915 return true ;
-
916 }
+
895
+
+ +
907 const std::string& label_text="",
+
908 const std::string& icon_path="",
+
909 bool toggleable=false,
+
910 const std::string& checkmark="✓",
+
911 const std::function<bool(void)>& callback=[] {return true ;},
+
912 const std::function<bool(void)>& unchecked_callback=[] {return true ;}) {
+
913 FluentMenu menu(toggleable, callback, unchecked_callback) ;
+
914 if(!menu.create_menu(
+
915 hinstance_, hwnd_, next_menu_id_,
+
916 label_text, icon_path, checkmark)) {
+
917 return false ;
+
918 }
+
919
+
920 menus_.push_back(std::move(menu)) ;
+
921 mouse_is_over_.push_back(false) ;
+
922 next_menu_id_ ++ ;
+
923 return true ;
+
924 }
-
917
-
- -
922 if(!menus_.empty()) {
-
923 menus_.back().show_separator_line() ;
-
924 }
-
925 }
+
925
+
+ +
930 if(!menus_.empty()) {
+
931 menus_.back().show_separator_line() ;
+
932 }
+
933 }
-
926
-
-
931 bool update() {
-
932 if(status_ == TrayStatus::FAILED) {
-
933 return false ;
-
934 }
-
935
-
936 MSG msg ;
-
937 get_message(msg) ;
-
938
-
939 if(GetForegroundWindow() != hwnd_ && visible_) {
-
940 if(!hide_menu_window()) {
-
941 fail() ;
-
942 return false ;
-
943 }
-
944 }
-
945
-
946 for(std::size_t i = 0 ; i < menus_.size() ; i ++) {
-
947 auto& menu = menus_[i] ;
-
948 if(menu.is_mouse_over()) {
-
949 if(!mouse_is_over_[i]) {
-
950 if(!change_menu_back_color(menu, ash_color_)) {
-
951 fail() ;
-
952 return false ;
-
953 }
-
954 }
-
955 mouse_is_over_[i] = true ;
-
956 }
-
957 else {
-
958 if(mouse_is_over_[i]) {
-
959 if(!change_menu_back_color(menu, back_color_)) {
-
960 fail() ;
-
961 return false ;
-
962 }
-
963 }
-
964 mouse_is_over_[i] = false ;
-
965 }
-
966 }
-
967
-
968 return true ;
-
969 }
+
934
+
+
939 bool update() {
+
940 if(status_ == TrayStatus::FAILED) {
+
941 return false ;
+
942 }
+
943
+
944 MSG msg ;
+
945 get_message(msg) ;
+
946
+
947 if(GetForegroundWindow() != hwnd_ && visible_) {
+
948 if(!hide_menu_window()) {
+
949 fail() ;
+
950 return false ;
+
951 }
+
952 }
+
953
+
954 for(std::size_t i = 0 ; i < menus_.size() ; i ++) {
+
955 auto& menu = menus_[i] ;
+
956 if(menu.is_mouse_over()) {
+
957 if(!mouse_is_over_[i]) {
+
958 if(!change_menu_back_color(menu, ash_color_)) {
+
959 fail() ;
+
960 return false ;
+
961 }
+
962 }
+
963 mouse_is_over_[i] = true ;
+
964 }
+
965 else {
+
966 if(mouse_is_over_[i]) {
+
967 if(!change_menu_back_color(menu, back_color_)) {
+
968 fail() ;
+
969 return false ;
+
970 }
+
971 }
+
972 mouse_is_over_[i] = false ;
+
973 }
+
974 }
+
975
+
976 return true ;
+
977 }
-
970
-
- -
977 std::chrono::milliseconds sleep_time=std::chrono::milliseconds(1)) {
978
-
979 while(true) {
-
980 if(status_ == TrayStatus::SHOULD_STOP) {
-
981 status_ = TrayStatus::STOPPED ;
-
982 break ;
-
983 }
-
984
-
985 if(!update()) {
-
986 return false ;
-
987 }
-
988
-
989 Sleep(static_cast<int>(sleep_time.count())) ;
-
990 }
-
991 return true ;
-
992 }
-
-
993
-
-
998 HWND window_handle() const noexcept {
-
999 return hwnd_ ;
+
+ +
985 std::chrono::milliseconds sleep_time=std::chrono::milliseconds(1)) {
+
986
+
987 while(true) {
+
988 if(status_ == TrayStatus::SHOULD_STOP) {
+
989 status_ = TrayStatus::STOPPED ;
+
990 break ;
+
991 }
+
992
+
993 if(!update()) {
+
994 return false ;
+
995 }
+
996
+
997 Sleep(static_cast<int>(sleep_time.count())) ;
+
998 }
+
999 return true ;
1000 }
1001
- -
1007 LONG max_label_size = 0 ;
-
1008 for(auto& menu : menus_) {
-
1009 SIZE size ;
-
1010 if(!menu.calculate_required_dims(font_, size)) {
-
1011 return false ;
-
1012 }
-
1013 if(max_label_size < size.cx) {
-
1014 max_label_size = size.cx ;
-
1015 }
-
1016 }
-
1017
-
1018 // Update the sizes
-
1019 auto menu_width = max_label_size + 2 * menu_x_pad_ ;
-
1020 auto menu_height = menu_font_size_ + 2 * menu_y_pad_ ;
-
1021 auto popup_width = 2 * menu_x_margin_ + menu_width ;
-
1022 auto popup_height = static_cast<LONG>(
-
1023 menus_.size() * (menu_y_margin_ + menu_height) + menu_y_margin_) ;
-
1024
-
1025 POINT cursor_pos ;
-
1026 if(!GetCursorPos(&cursor_pos)) {
-
1027 return false ;
-
1028 }
-
1029
-
1030 RECT work_rect ;
-
1031 if(!SystemParametersInfo(
-
1032 SPI_GETWORKAREA, 0, reinterpret_cast<PVOID>(&work_rect), 0)) {
-
1033 return false ;
-
1034 }
-
1035
-
1036 auto screen_width = GetSystemMetrics(SM_CXSCREEN) ;
-
1037 auto screen_height = GetSystemMetrics(SM_CYSCREEN) ;
-
1038
-
1039 auto work_width = work_rect.right - work_rect.left ;
-
1040 auto work_height = work_rect.bottom - work_rect.top ;
-
1041
-
1042 auto taskbar_width = screen_width - work_width ;
-
1043 auto taskbar_height = screen_height - work_height ;
-
1044
-
1045 auto pos = cursor_pos ;
-
1046 if(taskbar_width == 0) { // horizontal taskbar
-
1047 if(cursor_pos.y <= taskbar_height) {
-
1048 //top
-
1049 pos.y = taskbar_height ;
-
1050 }
-
1051 else {
-
1052 //bottom
-
1053 // add 20% offset
-
1054 pos.y = screen_height - (popup_height + 12 * taskbar_height / 10) ;
-
1055 }
-
1056 pos.x = cursor_pos.x - popup_width / 2 ;
-
1057 }
-
1058 else { // vertical taskbar
-
1059 if(pos.x <= taskbar_width) {
-
1060 //left
-
1061 pos.x = taskbar_width ;
-
1062 }
-
1063 else {
-
1064 //right
-
1065 // add 20% offset
-
1066 pos.x = popup_width + 12 * taskbar_width / 10 ;
-
1067 }
-
1068
-
1069 pos.y = cursor_pos.y - popup_height / 2 ;
-
1070 }
-
1071
-
1072 if(!SetWindowPos(
-
1073 hwnd_, HWND_TOP,
-
1074 pos.x, pos.y, popup_width, popup_height,
-
1075 SWP_SHOWWINDOW)) {
-
1076 return false ;
-
1077 }
-
1078
-
1079 for(std::size_t i = 0 ; i < menus_.size() ; i ++) {
-
1080 auto& menu = menus_[i] ;
-
1081 auto y = \
-
1082 menu_y_margin_
-
1083 + static_cast<LONG>(i) * (menu_height + menu_y_margin_) ;
-
1084 if(!SetWindowPos(
-
1085 menu.window_handle(), HWND_TOP,
-
1086 menu_x_margin_, y,
-
1087 menu_width, menu_height,
-
1088 SWP_SHOWWINDOW)) {
-
1089 return false ;
-
1090 }
-
1091
-
1092 if(!menu.set_color(text_color_, back_color_, ash_color_)) {
-
1093 return false ;
-
1094 }
-
1095 }
-
1096 std::fill(mouse_is_over_.begin(), mouse_is_over_.end(), false) ;
-
1097
-
1098 if(!SetForegroundWindow(hwnd_)) {
-
1099 return false ;
-
1100 }
-
1101
-
1102 visible_ = true ;
-
1103
-
1104 return true ;
-
1105 }
+
1006 HWND window_handle() const noexcept {
+
1007 return hwnd_ ;
+
1008 }
-
1106
-
- -
1112 ShowWindow(hwnd_, SW_HIDE) ;
-
1113 visible_ = false ;
-
1114 std::fill(mouse_is_over_.begin(), mouse_is_over_.end(), false) ;
-
1115 return true ;
-
1116 }
+
1009
+
+ +
1015 LONG max_label_size = 0 ;
+
1016 for(auto& menu : menus_) {
+
1017 SIZE size ;
+
1018 if(!menu.calculate_required_dims(font_, size)) {
+
1019 return false ;
+
1020 }
+
1021 if(max_label_size < size.cx) {
+
1022 max_label_size = size.cx ;
+
1023 }
+
1024 }
+
1025
+
1026 // Update the sizes
+
1027 auto menu_width = max_label_size + 2 * menu_x_pad_ ;
+
1028 auto menu_height = menu_font_size_ + 2 * menu_y_pad_ ;
+
1029 auto popup_width = 2 * menu_x_margin_ + menu_width ;
+
1030 auto popup_height = static_cast<LONG>(
+
1031 menus_.size() * (menu_y_margin_ + menu_height) + menu_y_margin_) ;
+
1032
+
1033 POINT cursor_pos ;
+
1034 if(!GetCursorPos(&cursor_pos)) {
+
1035 return false ;
+
1036 }
+
1037
+
1038 RECT work_rect ;
+
1039 if(!SystemParametersInfo(
+
1040 SPI_GETWORKAREA, 0, reinterpret_cast<PVOID>(&work_rect), 0)) {
+
1041 return false ;
+
1042 }
+
1043
+
1044 auto screen_width = GetSystemMetrics(SM_CXSCREEN) ;
+
1045 auto screen_height = GetSystemMetrics(SM_CYSCREEN) ;
+
1046
+
1047 auto work_width = work_rect.right - work_rect.left ;
+
1048 auto work_height = work_rect.bottom - work_rect.top ;
+
1049
+
1050 auto taskbar_width = screen_width - work_width ;
+
1051 auto taskbar_height = screen_height - work_height ;
+
1052
+
1053 auto pos = cursor_pos ;
+
1054 if(taskbar_width == 0) { // horizontal taskbar
+
1055 if(cursor_pos.y <= taskbar_height) {
+
1056 //top
+
1057 pos.y = taskbar_height ;
+
1058 }
+
1059 else {
+
1060 //bottom
+
1061 // add 20% offset
+
1062 pos.y = screen_height - (popup_height + 12 * taskbar_height / 10) ;
+
1063 }
+
1064 pos.x = cursor_pos.x - popup_width / 2 ;
+
1065 }
+
1066 else { // vertical taskbar
+
1067 if(pos.x <= taskbar_width) {
+
1068 //left
+
1069 pos.x = taskbar_width ;
+
1070 }
+
1071 else {
+
1072 //right
+
1073 // add 20% offset
+
1074 pos.x = popup_width + 12 * taskbar_width / 10 ;
+
1075 }
+
1076
+
1077 pos.y = cursor_pos.y - popup_height / 2 ;
+
1078 }
+
1079
+
1080 if(!SetWindowPos(
+
1081 hwnd_, HWND_TOP,
+
1082 pos.x, pos.y, popup_width, popup_height,
+
1083 SWP_SHOWWINDOW)) {
+
1084 return false ;
+
1085 }
+
1086
+
1087 for(std::size_t i = 0 ; i < menus_.size() ; i ++) {
+
1088 auto& menu = menus_[i] ;
+
1089 auto y = \
+
1090 menu_y_margin_
+
1091 + static_cast<LONG>(i) * (menu_height + menu_y_margin_) ;
+
1092 if(!SetWindowPos(
+
1093 menu.window_handle(), HWND_TOP,
+
1094 menu_x_margin_, y,
+
1095 menu_width, menu_height,
+
1096 SWP_SHOWWINDOW)) {
+
1097 return false ;
+
1098 }
+
1099
+
1100 if(!menu.set_color(text_color_, back_color_, ash_color_)) {
+
1101 return false ;
+
1102 }
+
1103 }
+
1104 std::fill(mouse_is_over_.begin(), mouse_is_over_.end(), false) ;
+
1105
+
1106 if(!SetForegroundWindow(hwnd_)) {
+
1107 return false ;
+
1108 }
+
1109
+
1110 visible_ = true ;
+
1111
+
1112 return true ;
+
1113 }
-
1117
-
-
1125 bool show_balloon_tip(const std::string& title, const std::string& message) {
-
1126 NOTIFYICONDATAW notify_data = {} ;
-
1127 notify_data.cbSize = sizeof(notify_data) ;
-
1128 notify_data.hWnd = hwnd_ ;
-
1129 notify_data.uFlags = NIF_INFO ;
-
1130
-
1131 std::wstring title_wide ;
-
1132 if(!util::string2wstring(title, title_wide)) {
-
1133 return false ;
-
1134 }
-
1135
-
1136 std::wstring message_wide ;
-
1137 if(!util::string2wstring(message, message_wide)) {
-
1138 return false ;
-
1139 }
-
1140
-
1141 auto title_len = title_wide.length() > 47 ? 47 : title_wide.length() ;
-
1142 std::wmemcpy(
-
1143 notify_data.szInfoTitle, title_wide.c_str(), title_len) ;
-
1144 notify_data.szInfoTitle[title_len] = L'\0' ;
-
1145
-
1146 auto message_len = message_wide.length() > 199 ? 199 : message_wide.length() ;
-
1147 std::wmemcpy(
-
1148 notify_data.szInfo, message_wide.c_str(), message_len) ;
-
1149 notify_data.szInfo[message_len] = L'\0' ;
-
1150
-
1151 if(!Shell_NotifyIconW(NIM_MODIFY, &notify_data)) {
-
1152 return false ;
-
1153 }
-
1154 return true ;
-
1155 }
+
1114
+
+ +
1120 ShowWindow(hwnd_, SW_HIDE) ;
+
1121 visible_ = false ;
+
1122 std::fill(mouse_is_over_.begin(), mouse_is_over_.end(), false) ;
+
1123 return true ;
+
1124 }
-
1156
-
-
1161 TrayStatus status() const noexcept {
-
1162 return status_ ;
+
1125
+
+
1133 bool show_balloon_tip(const std::string& title, const std::string& message) {
+
1134 NOTIFYICONDATAW notify_data = {} ;
+
1135 notify_data.cbSize = sizeof(notify_data) ;
+
1136 notify_data.hWnd = hwnd_ ;
+
1137 notify_data.uFlags = NIF_INFO ;
+
1138
+
1139 std::wstring title_wide ;
+
1140 if(!util::string2wstring(title, title_wide)) {
+
1141 return false ;
+
1142 }
+
1143
+
1144 std::wstring message_wide ;
+
1145 if(!util::string2wstring(message, message_wide)) {
+
1146 return false ;
+
1147 }
+
1148
+
1149 auto title_len = title_wide.length() > 47 ? 47 : title_wide.length() ;
+
1150 std::wmemcpy(
+
1151 notify_data.szInfoTitle, title_wide.c_str(), title_len) ;
+
1152 notify_data.szInfoTitle[title_len] = L'\0' ;
+
1153
+
1154 auto message_len = message_wide.length() > 199 ? 199 : message_wide.length() ;
+
1155 std::wmemcpy(
+
1156 notify_data.szInfo, message_wide.c_str(), message_len) ;
+
1157 notify_data.szInfo[message_len] = L'\0' ;
+
1158
+
1159 if(!Shell_NotifyIconW(NIM_MODIFY, &notify_data)) {
+
1160 return false ;
+
1161 }
+
1162 return true ;
1163 }
1164
-
-
1168 void stop() noexcept {
-
1169 status_ = TrayStatus::SHOULD_STOP ;
-
1170 }
+
+
1169 TrayStatus status() const noexcept {
+
1170 return status_ ;
+
1171 }
-
1171
+
1172
-
1176 std::vector<FluentMenu>::iterator begin() noexcept {
-
1177 return menus_.begin() ;
+
1176 void stop() noexcept {
+
1177 status_ = TrayStatus::SHOULD_STOP ;
1178 }
1179
-
1184 std::vector<FluentMenu>::iterator end() noexcept {
-
1185 return menus_.end() ;
+
1184 std::vector<FluentMenu>::iterator begin() noexcept {
+
1185 return menus_.begin() ;
1186 }
1187
-
1192 std::vector<FluentMenu>::const_iterator cbegin() const noexcept {
-
1193 return menus_.cbegin() ;
+
1192 std::vector<FluentMenu>::iterator end() noexcept {
+
1193 return menus_.end() ;
1194 }
1195
-
1200 std::vector<FluentMenu>::const_iterator cend() const noexcept {
-
1201 return menus_.cend() ;
+
1200 std::vector<FluentMenu>::const_iterator cbegin() const noexcept {
+
1201 return menus_.cbegin() ;
1202 }
1203
- -
1209 return menus_.front() ;
+
1208 std::vector<FluentMenu>::const_iterator cend() const noexcept {
+
1209 return menus_.cend() ;
1210 }
1211
-
1216 const FluentMenu& front() const {
+
1217 return menus_.front() ;
1218 }
1219
- -
1225 return menus_.back() ;
+
1224 const FluentMenu& front() const {
+
1225 return menus_.front() ;
1226 }
1227
-
1232 const FluentMenu& back() const {
+
1233 return menus_.back() ;
1234 }
1235
-
1240 std::size_t count_menus() const noexcept {
-
1241 return menus_.size() ;
+
1240 const FluentMenu& back() const {
+
1241 return menus_.back() ;
1242 }
1243
-
- -
1253 LONG font_size=0,
-
1254 LONG font_weight=0,
-
1255 const std::string& font_name="") {
-
1256 NONCLIENTMETRICSW metrics ;
-
1257 metrics.cbSize = sizeof(metrics) ;
-
1258
-
1259 if(!SystemParametersInfoW(
-
1260 SPI_GETNONCLIENTMETRICS,
-
1261 metrics.cbSize, &metrics, 0)) {
-
1262 return false ;
-
1263 }
-
1264
-
1265 auto& logfont = metrics.lfCaptionFont ;
-
1266 if(font_size != 0) {
-
1267 logfont.lfHeight = font_size ;
-
1268 }
-
1269 else {
-
1270 logfont.lfHeight = 20 ;
+
+
1248 std::size_t count_menus() const noexcept {
+
1249 return menus_.size() ;
+
1250 }
+
+
1251
+
+ +
1261 LONG font_size=0,
+
1262 LONG font_weight=0,
+
1263 const std::string& font_name="") {
+
1264 NONCLIENTMETRICSW metrics ;
+
1265 metrics.cbSize = sizeof(metrics) ;
+
1266
+
1267 if(!SystemParametersInfoW(
+
1268 SPI_GETNONCLIENTMETRICS,
+
1269 metrics.cbSize, &metrics, 0)) {
+
1270 return false ;
1271 }
-
1272 if(font_weight != 0) {
-
1273 logfont.lfWeight = font_weight ;
-
1274 }
-
1275 else {
-
1276 logfont.lfWeight = FW_MEDIUM ;
-
1277 }
-
1278
-
1279 if(!font_name.empty()) {
-
1280 std::wstring font_name_wide ;
-
1281 if(!util::string2wstring(font_name, font_name_wide)) {
-
1282 return false ;
-
1283 }
-
1284 auto& dst = logfont.lfFaceName ;
-
1285
-
1286 if(font_name_wide.size() < LF_FACESIZE) {
-
1287 std::wmemcpy(
-
1288 dst, font_name_wide.c_str(), font_name_wide.length()) ;
-
1289 dst[font_name_wide.size()] = L'\0' ;
-
1290 }
-
1291 else {
-
1292 std::wmemcpy(
-
1293 dst, font_name_wide.c_str(), LF_FACESIZE - 1) ;
-
1294 dst[LF_FACESIZE - 1] = L'\0' ;
-
1295 }
-
1296 }
-
1297
-
1298 auto font = CreateFontIndirectW(&logfont) ;
-
1299 if(!font) {
-
1300 return false ;
-
1301 }
-
1302 font_ = font ;
-
1303 menu_font_size_ = std::abs(logfont.lfHeight) ;
-
1304
-
1305 return true;
-
1306 }
+
1272
+
1273 auto& logfont = metrics.lfCaptionFont ;
+
1274 if(font_size != 0) {
+
1275 logfont.lfHeight = font_size ;
+
1276 }
+
1277 else {
+
1278 logfont.lfHeight = 20 ;
+
1279 }
+
1280 if(font_weight != 0) {
+
1281 logfont.lfWeight = font_weight ;
+
1282 }
+
1283 else {
+
1284 logfont.lfWeight = FW_MEDIUM ;
+
1285 }
+
1286
+
1287 if(!font_name.empty()) {
+
1288 std::wstring font_name_wide ;
+
1289 if(!util::string2wstring(font_name, font_name_wide)) {
+
1290 return false ;
+
1291 }
+
1292 auto& dst = logfont.lfFaceName ;
+
1293
+
1294 if(font_name_wide.size() < LF_FACESIZE) {
+
1295 std::wmemcpy(
+
1296 dst, font_name_wide.c_str(), font_name_wide.length()) ;
+
1297 dst[font_name_wide.size()] = L'\0' ;
+
1298 }
+
1299 else {
+
1300 std::wmemcpy(
+
1301 dst, font_name_wide.c_str(), LF_FACESIZE - 1) ;
+
1302 dst[LF_FACESIZE - 1] = L'\0' ;
+
1303 }
+
1304 }
+
1305
+
1306 auto font = CreateFontIndirectW(&logfont) ;
+
1307 if(!font) {
+
1308 return false ;
+
1309 }
+
1310 font_ = font ;
+
1311 menu_font_size_ = std::abs(logfont.lfHeight) ;
+
1312
+
1313 return true;
+
1314 }
-
1307
-
- -
1316 const COLORREF& text_color=CLR_INVALID,
-
1317 const COLORREF& back_color=CLR_INVALID,
-
1318 unsigned char color_decay=10) {
-
1319 if(back_color == CLR_INVALID) {
-
1320 // Get Taskbar color
-
1321 APPBARDATA abd ;
-
1322 abd.cbSize = sizeof(abd) ;
-
1323 if(!SHAppBarMessage(ABM_GETTASKBARPOS, &abd)) {
-
1324 return false ;
-
1325 }
-
1326
-
1327 if(auto dc = GetDC(NULL)) {
-
1328 // Get Taskbar color
-
1329 back_color_ = GetPixel(dc, abd.rc.left + 1, abd.rc.top + 1) ;
-
1330 if(back_color_ == CLR_INVALID) {
-
1331 // if failed, use COLOR_WINDOW color.
-
1332 back_color_ = GetSysColor(COLOR_WINDOW) ;
-
1333 }
-
1334 if(!ReleaseDC(NULL, dc)) {
-
1335 return false ;
-
1336 }
-
1337 }
-
1338 }
-
1339 else {
-
1340 back_color_ = back_color ;
-
1341 }
-
1342
-
1343 auto back_gray_color_ = util::rgb2gray(back_color_) ;
-
1344
-
1345 unsigned char ash_value = back_gray_color_ ;
-
1346 if(back_gray_color_ < 128) {
-
1347 ash_value = static_cast<decltype(ash_value)>(
-
1348 (std::min)(ash_value + color_decay, 255)) ;
+
1315
+
+ +
1324 const COLORREF& text_color=CLR_INVALID,
+
1325 const COLORREF& back_color=CLR_INVALID,
+
1326 unsigned char color_decay=10) {
+
1327 if(back_color == CLR_INVALID) {
+
1328 // Get Taskbar color
+
1329 APPBARDATA abd ;
+
1330 abd.cbSize = sizeof(abd) ;
+
1331 if(!SHAppBarMessage(ABM_GETTASKBARPOS, &abd)) {
+
1332 return false ;
+
1333 }
+
1334
+
1335 if(auto dc = GetDC(NULL)) {
+
1336 // Get Taskbar color
+
1337 back_color_ = GetPixel(
+
1338 dc,
+
1339 abd.rc.left + FLUENT_TRAY_COLORPICK_OFFSET,
+
1340 abd.rc.top + FLUENT_TRAY_COLORPICK_OFFSET) ;
+
1341 if(back_color_ == CLR_INVALID) {
+
1342 // if failed, use COLOR_WINDOW color.
+
1343 back_color_ = GetSysColor(COLOR_WINDOW) ;
+
1344 }
+
1345 if(!ReleaseDC(NULL, dc)) {
+
1346 return false ;
+
1347 }
+
1348 }
1349 }
1350 else {
-
1351 ash_value = static_cast<decltype(ash_value)>(
-
1352 (std::max)(ash_value - color_decay, 0)) ;
-
1353 }
-
1354 ash_color_ = RGB(ash_value, ash_value, ash_value) ;
+
1351 back_color_ = back_color ;
+
1352 }
+
1353
+
1354 auto back_gray_color_ = util::rgb2gray(back_color_) ;
1355
-
1356 if(text_color == CLR_INVALID) {
-
1357 text_color_ = GetSysColor(COLOR_WINDOWTEXT) ;
-
1358 if(back_gray_color_ < 128) {
-
1359 // if dark background, use light text color.
-
1360 text_color_ = 0x00FFFFFF & ~text_color_ ;
-
1361 }
-
1362 }
-
1363 else {
-
1364 text_color_ = text_color ;
-
1365 }
+
1356 unsigned char ash_value = back_gray_color_ ;
+
1357 if(back_gray_color_ < 128) {
+
1358 ash_value = static_cast<decltype(ash_value)>(
+
1359 (std::min)(ash_value + color_decay, 255)) ;
+
1360 }
+
1361 else {
+
1362 ash_value = static_cast<decltype(ash_value)>(
+
1363 (std::max)(ash_value - color_decay, 0)) ;
+
1364 }
+
1365 ash_color_ = RGB(ash_value, ash_value, ash_value) ;
1366
-
1367 if(back_brush_) {
-
1368 // Release old handle.
-
1369 if(!DeleteObject(back_brush_)) {
-
1370 return false ;
-
1371 }
-
1372 }
-
1373 back_brush_ = CreateSolidBrush(back_color_) ;
-
1374 if(back_brush_ == NULL) {
-
1375 return false ;
+
1367 if(text_color == CLR_INVALID) {
+
1368 text_color_ = GetSysColor(COLOR_WINDOWTEXT) ;
+
1369 if(back_gray_color_ < 128) {
+
1370 // if dark background, use light text color.
+
1371 text_color_ = 0x00FFFFFF & ~text_color_ ;
+
1372 }
+
1373 }
+
1374 else {
+
1375 text_color_ = text_color ;
1376 }
1377
-
1378 if(!SetClassLongPtr(
-
1379 hwnd_, GCLP_HBRBACKGROUND,
-
1380 reinterpret_cast<LONG_PTR>(back_brush_))) {
-
1381 return false ;
-
1382 }
-
1383
-
1384 return true ;
-
1385 }
+
1378 if(back_brush_) {
+
1379 // Release old handle.
+
1380 if(!DeleteObject(back_brush_)) {
+
1381 return false ;
+
1382 }
+
1383 }
+
1384 back_brush_ = CreateSolidBrush(back_color_) ;
+
1385 if(back_brush_ == NULL) {
+
1386 return false ;
+
1387 }
+
1388
+
1389 if(!SetClassLongPtr(
+
1390 hwnd_, GCLP_HBRBACKGROUND,
+
1391 reinterpret_cast<LONG_PTR>(back_brush_))) {
+
1392 return false ;
+
1393 }
+
1394
+
1395 return true ;
+
1396 }
-
1386
-
-
1391 bool change_icon(const std::string& icon_path) {
-
1392 if(icon_data_.cbSize > 0) {
-
1393 if(!Shell_NotifyIconW(NIM_DELETE, &icon_data_)) {
-
1394 return false ;
-
1395 }
-
1396 }
1397
-
1398 ZeroMemory(&icon_data_, sizeof(icon_data_)) ;
-
1399
-
1400 if(icon_path.empty()) {
-
1401 icon_data_.cbSize = 0 ;
-
1402 return true ;
-
1403 }
-
1404
-
1405 std::wstring icon_path_wide ;
-
1406 if(!util::string2wstring(icon_path, icon_path_wide)) {
-
1407 return false ;
-
1408 }
-
1409
-
1410 if(!util::exists(icon_path_wide)) {
-
1411 return false ;
-
1412 }
-
1413
-
1414 icon_data_.cbSize = sizeof(icon_data_) ;
-
1415 icon_data_.hWnd = hwnd_ ;
-
1416 icon_data_.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP ;
-
1417 icon_data_.uCallbackMessage = MESSAGE_ID ;
-
1418 icon_data_.hIcon = static_cast<HICON>(
-
1419 LoadImageW(
-
1420 NULL, icon_path_wide.c_str(),
-
1421 IMAGE_ICON, 0, 0, LR_LOADFROMFILE)) ;
-
1422 wcscpy_s(icon_data_.szTip, app_name_.c_str()) ;
-
1423 icon_data_.dwState = NIS_SHAREDICON ;
-
1424 icon_data_.dwStateMask = NIS_SHAREDICON ;
-
1425
-
1426 if(!Shell_NotifyIconW(NIM_ADD, &icon_data_)) {
-
1427 return false ;
-
1428 }
- -
1430
-
1431 return true ;
-
1432 }
+
+
1402 bool change_icon(const std::string& icon_path) {
+
1403 if(icon_data_.cbSize > 0) {
+
1404 if(!Shell_NotifyIconW(NIM_DELETE, &icon_data_)) {
+
1405 return false ;
+
1406 }
+
1407 }
+
1408
+
1409 ZeroMemory(&icon_data_, sizeof(icon_data_)) ;
+
1410
+
1411 if(icon_path.empty()) {
+
1412 icon_data_.cbSize = 0 ;
+
1413 return true ;
+
1414 }
+
1415
+
1416 std::wstring icon_path_wide ;
+
1417 if(!util::string2wstring(icon_path, icon_path_wide)) {
+
1418 return false ;
+
1419 }
+
1420
+
1421 if(!util::exists(icon_path_wide)) {
+
1422 return false ;
+
1423 }
+
1424
+
1425 icon_data_.cbSize = sizeof(icon_data_) ;
+
1426 icon_data_.hWnd = hwnd_ ;
+
1427 icon_data_.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP ;
+
1428 icon_data_.uCallbackMessage = MESSAGE_ID ;
+
1429 icon_data_.hIcon = static_cast<HICON>(
+
1430 LoadImageW(
+
1431 NULL, icon_path_wide.c_str(),
+
1432 IMAGE_ICON, 0, 0, LR_LOADFROMFILE)) ;
+
1433 wcscpy_s(icon_data_.szTip, app_name_.c_str()) ;
+
1434 icon_data_.dwState = NIS_SHAREDICON ;
+
1435 icon_data_.dwStateMask = NIS_SHAREDICON ;
+
1436
+
1437 if(!Shell_NotifyIconW(NIM_ADD, &icon_data_)) {
+
1438 return false ;
+
1439 }
+ +
1441
+
1442 return true ;
+
1443 }
-
1433
-
1434 private:
-
1435 static LRESULT CALLBACK callback(
-
1436 HWND hwnd,
-
1437 UINT msg,
-
1438 WPARAM wparam,
-
1439 LPARAM lparam) {
-
1440 auto get_instance = [hwnd]() -> FluentTray* {
-
1441 auto upper_addr = GetWindowLongW(hwnd, 0) ;
-
1442 if(!upper_addr) {
-
1443 return nullptr ;
-
1444 }
-
1445
-
1446 auto lower_addr = GetWindowLongW(hwnd, sizeof(LONG)) ;
-
1447 if(!lower_addr) {
-
1448 return nullptr ;
-
1449 }
-
1450
-
1451 FluentTray* self ;
-
1452 util::concatenate_bits(upper_addr, lower_addr, self) ;
-
1453 return self ;
-
1454 } ;
-
1455
-
1456 if(msg == WM_DESTROY || msg == WM_QUIT || msg == WM_CLOSE) {
-
1457 if(auto self = get_instance()) {
-
1458 self->stop() ;
-
1459 return 0 ;
+
1444
+
1445 private:
+
1446 static LRESULT CALLBACK callback(
+
1447 HWND hwnd,
+
1448 UINT msg,
+
1449 WPARAM wparam,
+
1450 LPARAM lparam) {
+
1451 auto get_instance = [hwnd]() -> FluentTray* {
+
1452 auto upper_addr = GetWindowLongW(hwnd, 0) ;
+
1453 if(!upper_addr) {
+
1454 return nullptr ;
+
1455 }
+
1456
+
1457 auto lower_addr = GetWindowLongW(hwnd, sizeof(LONG)) ;
+
1458 if(!lower_addr) {
+
1459 return nullptr ;
1460 }
-
1461 }
-
1462 else if(msg == WM_ACTIVATE && wparam == WA_INACTIVE) {
-
1463 if(auto self = get_instance()) {
-
1464 if(!self->hide_menu_window()) {
-
1465 self->fail() ;
-
1466 }
-
1467 return 0 ;
-
1468 }
-
1469 }
-
1470 else if(msg == WM_DRAWITEM) {
-
1471 if(auto self = get_instance()) {
-
1472 auto item = reinterpret_cast<LPDRAWITEMSTRUCT>(lparam) ;
-
1473 auto menu_idx = self->get_menu_index_from_window(item->hwndItem) ;
-
1474 if(menu_idx < 0) {
-
1475 return FALSE ;
-
1476 }
-
1477 auto& menu = self->menus_[menu_idx] ;
-
1478 if(!menu.draw_menu(item, self->font_)) {
-
1479 self->fail() ;
-
1480 return FALSE ;
-
1481 }
-
1482 return TRUE ;
-
1483 }
-
1484 }
-
1485 else if(msg == WM_CTLCOLORBTN) {
-
1486 if(auto self = get_instance()) {
-
1487 auto menu_idx = self->get_menu_index_from_window(reinterpret_cast<HWND>(lparam)) ;
-
1488 if(menu_idx < 0) {
-
1489 return DefWindowProc(hwnd, msg, wparam, lparam) ;
-
1490 }
-
1491 auto& menu = self->menus_[menu_idx] ;
-
1492 return reinterpret_cast<LRESULT>(menu.background_brush()) ;
-
1493 }
-
1494 }
-
1495 else if(msg == WM_COMMAND) {
-
1496 if(auto self = get_instance()) {
-
1497 auto menu_idx = self->get_menu_index_from_id(LOWORD(wparam)) ;
-
1498 if(menu_idx < 0) {
-
1499 return FALSE ;
-
1500 }
-
1501 auto& menu = self->menus_[menu_idx] ;
-
1502 if(!menu.process_click_event()) {
-
1503 self->stop() ;
-
1504 return FALSE ;
-
1505 }
-
1506 if(menu.is_toggleable()) {
-
1507 // Update the toggle menu for checkmark
-
1508 if(!InvalidateRect(menu.window_handle(), NULL, TRUE)) {
-
1509 return false ;
-
1510 }
+
1461
+
1462 FluentTray* self ;
+
1463 util::concatenate_bits(upper_addr, lower_addr, self) ;
+
1464 return self ;
+
1465 } ;
+
1466
+
1467 if(msg == WM_DESTROY || msg == WM_QUIT || msg == WM_CLOSE) {
+
1468 if(auto self = get_instance()) {
+
1469 self->stop() ;
+
1470 return 0 ;
+
1471 }
+
1472 }
+
1473 else if(msg == WM_ACTIVATE && wparam == WA_INACTIVE) {
+
1474 if(auto self = get_instance()) {
+
1475 if(!self->hide_menu_window()) {
+
1476 self->fail() ;
+
1477 }
+
1478 return 0 ;
+
1479 }
+
1480 }
+
1481 else if(msg == WM_DRAWITEM) {
+
1482 if(auto self = get_instance()) {
+
1483 auto item = reinterpret_cast<LPDRAWITEMSTRUCT>(lparam) ;
+
1484 auto menu_idx = self->get_menu_index_from_window(item->hwndItem) ;
+
1485 if(menu_idx < 0) {
+
1486 return FALSE ;
+
1487 }
+
1488 auto& menu = self->menus_[menu_idx] ;
+
1489 if(!menu.draw_menu(item, self->font_)) {
+
1490 self->fail() ;
+
1491 return FALSE ;
+
1492 }
+
1493 return TRUE ;
+
1494 }
+
1495 }
+
1496 else if(msg == WM_CTLCOLORBTN) {
+
1497 if(auto self = get_instance()) {
+
1498 auto menu_idx = self->get_menu_index_from_window(reinterpret_cast<HWND>(lparam)) ;
+
1499 if(menu_idx < 0) {
+
1500 return DefWindowProc(hwnd, msg, wparam, lparam) ;
+
1501 }
+
1502 auto& menu = self->menus_[menu_idx] ;
+
1503 return reinterpret_cast<LRESULT>(menu.background_brush()) ;
+
1504 }
+
1505 }
+
1506 else if(msg == WM_COMMAND) {
+
1507 if(auto self = get_instance()) {
+
1508 auto menu_idx = self->get_menu_index_from_id(LOWORD(wparam)) ;
+
1509 if(menu_idx < 0) {
+
1510 return FALSE ;
1511 }
-
1512 return TRUE ;
-
1513 }
-
1514 }
-
1515 else if(msg == MESSAGE_ID) { //On NotifyIcon
-
1516 if(auto self = get_instance()) {
-
1517 if(lparam == WM_LBUTTONUP || lparam == WM_RBUTTONUP) {
-
1518 self->show_menu_window() ;
-
1519 return 0 ;
-
1520 }
-
1521 }
-
1522 }
-
1523
-
1524 return DefWindowProc(hwnd, msg, wparam, lparam) ;
-
1525 }
-
1526
-
1527 int get_menu_index_from_window(HWND hwnd) {
-
1528 int i = 0 ;
-
1529 for(auto& m : menus_) {
-
1530 if(m.window_handle() == hwnd) {
-
1531 return i ;
-
1532 }
-
1533 i ++ ;
-
1534 }
-
1535 return -1 ;
-
1536 }
-
1537
-
1538 int get_menu_index_from_id(WORD id) {
-
1539 int i = 0 ;
-
1540 for(auto& m : menus_) {
-
1541 if(m.id() == static_cast<std::size_t>(id)) {
-
1542 return i ;
-
1543 }
-
1544 i ++ ;
-
1545 }
-
1546 return -1 ;
-
1547 }
-
1548
-
1549 void get_message(MSG& message) {
-
1550 if(PeekMessage(&message, hwnd_, 0, 0, PM_REMOVE)) {
-
1551 DispatchMessage(&message) ;
-
1552 }
-
1553 }
-
1554
-
1555 void fail() noexcept {
-
1556 status_ = TrayStatus::FAILED ;
-
1557 }
-
1558
-
1559 bool change_menu_back_color(FluentMenu& menu, COLORREF new_color) {
-
1560 if(!menu.set_color(
-
1561 text_color_, new_color, ash_color_)) {
-
1562 return false ;
-
1563 }
-
1564 // Redraw
-
1565 if(!InvalidateRect(menu.window_handle(), NULL, TRUE)) {
-
1566 return false ;
-
1567 }
-
1568 return true ;
+
1512 auto& menu = self->menus_[menu_idx] ;
+
1513 if(!menu.process_click_event()) {
+
1514 self->stop() ;
+
1515 return FALSE ;
+
1516 }
+
1517 if(menu.is_toggleable()) {
+
1518 // Update the toggle menu for checkmark
+
1519 if(!InvalidateRect(menu.window_handle(), NULL, TRUE)) {
+
1520 return FALSE ;
+
1521 }
+
1522 }
+
1523 else {
+
1524 if(!self->hide_menu_window()) {
+
1525 return FALSE ;
+
1526 }
+
1527 }
+
1528 return TRUE ;
+
1529 }
+
1530 }
+
1531 else if(msg == MESSAGE_ID) { //On NotifyIcon
+
1532 if(auto self = get_instance()) {
+
1533 if(lparam == WM_LBUTTONUP || lparam == WM_RBUTTONUP) {
+
1534 self->show_menu_window() ;
+
1535 return 0 ;
+
1536 }
+
1537 }
+
1538 }
+
1539
+
1540 return DefWindowProc(hwnd, msg, wparam, lparam) ;
+
1541 }
+
1542
+
1543 int get_menu_index_from_window(HWND hwnd) {
+
1544 int i = 0 ;
+
1545 for(auto& m : menus_) {
+
1546 if(m.window_handle() == hwnd) {
+
1547 return i ;
+
1548 }
+
1549 i ++ ;
+
1550 }
+
1551 return -1 ;
+
1552 }
+
1553
+
1554 int get_menu_index_from_id(WORD id) {
+
1555 int i = 0 ;
+
1556 for(auto& m : menus_) {
+
1557 if(m.id() == static_cast<std::size_t>(id)) {
+
1558 return i ;
+
1559 }
+
1560 i ++ ;
+
1561 }
+
1562 return -1 ;
+
1563 }
+
1564
+
1565 void get_message(MSG& message) {
+
1566 if(PeekMessage(&message, hwnd_, 0, 0, PM_REMOVE)) {
+
1567 DispatchMessage(&message) ;
+
1568 }
1569 }
-
1570 } ;
+
1570
+
1571 void fail() noexcept {
+
1572 status_ = TrayStatus::FAILED ;
+
1573 }
+
1574
+
1575 bool change_menu_back_color(FluentMenu& menu, COLORREF new_color) {
+
1576 if(!menu.set_color(
+
1577 text_color_, new_color, ash_color_)) {
+
1578 return false ;
+
1579 }
+
1580 // Redraw
+
1581 if(!InvalidateRect(menu.window_handle(), NULL, TRUE)) {
+
1582 return false ;
+
1583 }
+
1584 return true ;
+
1585 }
+
1586 } ;
-
1571}
-
1572
-
1573#endif
-
Class with information on each menu.
Definition fluent_tray.hpp:258
-
bool is_mouse_over() const
Checks whether the mouse cursor is over the menu or not.
Definition fluent_tray.hpp:403
-
bool set_color(const COLORREF &text_color=CLR_INVALID, const COLORREF &back_color=CLR_INVALID, const COLORREF &border_color=CLR_INVALID) noexcept
Set the menu color.
Definition fluent_tray.hpp:508
-
FluentMenu(bool toggleable=false, const std::function< bool(void)> &callback=[] {return true ;}, const std::function< bool(void)> &unchecked_callback=[] {return true ;})
Create menu object.
Definition fluent_tray.hpp:288
+
1587}
+
1588
+
1589#endif
+
Class with information on each menu.
Definition fluent_tray.hpp:266
+
bool is_mouse_over() const
Checks whether the mouse cursor is over the menu or not.
Definition fluent_tray.hpp:411
+
bool set_color(const COLORREF &text_color=CLR_INVALID, const COLORREF &back_color=CLR_INVALID, const COLORREF &border_color=CLR_INVALID) noexcept
Set the menu color.
Definition fluent_tray.hpp:516
+
FluentMenu(bool toggleable=false, const std::function< bool(void)> &callback=[] {return true ;}, const std::function< bool(void)> &unchecked_callback=[] {return true ;})
Create menu object.
Definition fluent_tray.hpp:296
FluentMenu & operator=(FluentMenu &&)=default
-
bool draw_menu(LPDRAWITEMSTRUCT info, HFONT font) const
Draws a menu using drawing information and the specified font.
Definition fluent_tray.hpp:544
+
bool draw_menu(LPDRAWITEMSTRUCT info, HFONT font) const
Draws a menu using drawing information and the specified font.
Definition fluent_tray.hpp:552
FluentMenu(FluentMenu &&)=default
-
void show_separator_line() noexcept
Show a separator line under the menu.
Definition fluent_tray.hpp:489
-
HMENU menu_handle() const noexcept
Refer to the menu handle.
Definition fluent_tray.hpp:466
+
void show_separator_line() noexcept
Show a separator line under the menu.
Definition fluent_tray.hpp:497
+
HMENU menu_handle() const noexcept
Refer to the menu handle.
Definition fluent_tray.hpp:474
FluentMenu & operator=(const FluentMenu &)=default
-
std::size_t id() const noexcept
Refer to the menu identifier.
Definition fluent_tray.hpp:474
-
bool is_checked() const noexcept
Refer to the check status of the menu.
Definition fluent_tray.hpp:439
-
bool is_toggleable() const noexcept
Check if the menu is toggleable.
Definition fluent_tray.hpp:450
-
~FluentMenu() noexcept
Definition fluent_tray.hpp:314
-
bool create_menu(HINSTANCE hinstance, HWND parent_hwnd, std::size_t id, const std::string &label_text="", const std::string &icon_path="", const std::string &checkmark="✓")
Creates a menu window.
Definition fluent_tray.hpp:330
-
void uncheck() noexcept
Unchecks the menu if it is toggleable.
Definition fluent_tray.hpp:429
-
bool calculate_required_dims(HFONT font, SIZE &size) const
Calculates the size of the bounding box surrounding the menu based on the font information and the le...
Definition fluent_tray.hpp:630
-
HWND window_handle() const noexcept
Refer to the menu window handle.
Definition fluent_tray.hpp:458
-
void hide_separator_line() noexcept
Hide a separator line under the menu.
Definition fluent_tray.hpp:496
-
bool process_click_event()
Execute the process when clicked on the menu.
Definition fluent_tray.hpp:389
-
HBRUSH background_brush() const noexcept
Refer to the brush for drawing the background.
Definition fluent_tray.hpp:621
-
bool get_label(std::string &str) const
Get menu label as UTF-8 string.
Definition fluent_tray.hpp:482
-
void check() noexcept
Checks the menu if it is toggleable.
Definition fluent_tray.hpp:419
+
std::size_t id() const noexcept
Refer to the menu identifier.
Definition fluent_tray.hpp:482
+
bool is_checked() const noexcept
Refer to the check status of the menu.
Definition fluent_tray.hpp:447
+
bool is_toggleable() const noexcept
Check if the menu is toggleable.
Definition fluent_tray.hpp:458
+
~FluentMenu() noexcept
Definition fluent_tray.hpp:322
+
bool create_menu(HINSTANCE hinstance, HWND parent_hwnd, std::size_t id, const std::string &label_text="", const std::string &icon_path="", const std::string &checkmark="✓")
Creates a menu window.
Definition fluent_tray.hpp:338
+
void uncheck() noexcept
Unchecks the menu if it is toggleable.
Definition fluent_tray.hpp:437
+
bool calculate_required_dims(HFONT font, SIZE &size) const
Calculates the size of the bounding box surrounding the menu based on the font information and the le...
Definition fluent_tray.hpp:638
+
HWND window_handle() const noexcept
Refer to the menu window handle.
Definition fluent_tray.hpp:466
+
void hide_separator_line() noexcept
Hide a separator line under the menu.
Definition fluent_tray.hpp:504
+
bool process_click_event()
Execute the process when clicked on the menu.
Definition fluent_tray.hpp:397
+
HBRUSH background_brush() const noexcept
Refer to the brush for drawing the background.
Definition fluent_tray.hpp:629
+
bool get_label(std::string &str) const
Get menu label as UTF-8 string.
Definition fluent_tray.hpp:490
+
void check() noexcept
Checks the menu if it is toggleable.
Definition fluent_tray.hpp:427
FluentMenu(const FluentMenu &)=default
-
Class with information on the entire tray.
Definition fluent_tray.hpp:680
-
bool show_balloon_tip(const std::string &title, const std::string &message)
Shows a balloon tip that is placed in the notification area.
Definition fluent_tray.hpp:1125
-
virtual ~FluentTray() noexcept
Definition fluent_tray.hpp:744
-
std::vector< FluentMenu >::iterator end() noexcept
Returns an iterator to the end of menus.
Definition fluent_tray.hpp:1184
+
Class with information on the entire tray.
Definition fluent_tray.hpp:688
+
bool show_balloon_tip(const std::string &title, const std::string &message)
Shows a balloon tip that is placed in the notification area.
Definition fluent_tray.hpp:1133
+
virtual ~FluentTray() noexcept
Definition fluent_tray.hpp:752
+
std::vector< FluentMenu >::iterator end() noexcept
Returns an iterator to the end of menus.
Definition fluent_tray.hpp:1192
FluentTray & operator=(const FluentTray &)=delete
-
bool show_menu_window()
Show the menu window above the tray icon.
Definition fluent_tray.hpp:1006
-
bool create_tray(const std::string &app_name, const std::string &icon_path="", LONG menu_x_margin=5, LONG menu_y_margin=5, LONG menu_x_pad=5, LONG menu_y_pad=5, unsigned char opacity=255, bool round_corner=true)
Initialize tray and create icon on tray.
Definition fluent_tray.hpp:765
-
void stop() noexcept
Exit the tray successfully.
Definition fluent_tray.hpp:1168
+
bool show_menu_window()
Show the menu window above the tray icon.
Definition fluent_tray.hpp:1014
+
bool create_tray(const std::string &app_name, const std::string &icon_path="", LONG menu_x_margin=5, LONG menu_y_margin=5, LONG menu_x_pad=5, LONG menu_y_pad=5, unsigned char opacity=255, bool round_corner=true)
Initialize tray and create icon on tray.
Definition fluent_tray.hpp:773
+
void stop() noexcept
Exit the tray successfully.
Definition fluent_tray.hpp:1176
FluentTray & operator=(FluentTray &&)=default
-
bool add_menu(const std::string &label_text="", const std::string &icon_path="", bool toggleable=false, const std::string &checkmark="✓", const std::function< bool(void)> &callback=[] {return true ;}, const std::function< bool(void)> &unchecked_callback=[] {return true ;})
Add a menu in order from the top.
Definition fluent_tray.hpp:898
-
bool set_font(LONG font_size=0, LONG font_weight=0, const std::string &font_name="")
Set font information to draw menus.
Definition fluent_tray.hpp:1252
-
TrayStatus status() const noexcept
Get the current status of tray.
Definition fluent_tray.hpp:1161
-
const FluentMenu & back() const
Returns the const reference to the last of menus.
Definition fluent_tray.hpp:1232
-
bool change_icon(const std::string &icon_path)
Load the image file and change the icon.
Definition fluent_tray.hpp:1391
-
FluentTray()
Create tray object.
Definition fluent_tray.hpp:714
-
std::size_t count_menus() const noexcept
Returns the number of menus.
Definition fluent_tray.hpp:1240
-
bool update_with_loop(std::chrono::milliseconds sleep_time=std::chrono::milliseconds(1))
Create a message loop to update the tray.
Definition fluent_tray.hpp:976
-
std::vector< FluentMenu >::const_iterator cbegin() const noexcept
Returns a constant iterator to the beginning of menus.
Definition fluent_tray.hpp:1192
-
std::vector< FluentMenu >::const_iterator cend() const noexcept
Returns a constant iterator to the end of menus.
Definition fluent_tray.hpp:1200
-
const FluentMenu & front() const
Returns the const reference to the beginning of menus.
Definition fluent_tray.hpp:1216
-
bool set_color(const COLORREF &text_color=CLR_INVALID, const COLORREF &back_color=CLR_INVALID, unsigned char color_decay=10)
Set colors to draw menus.
Definition fluent_tray.hpp:1315
-
void add_separator()
Add a separator line under the last menu item added.
Definition fluent_tray.hpp:921
-
bool hide_menu_window()
Hide the menu window above the tray icon.
Definition fluent_tray.hpp:1111
+
bool add_menu(const std::string &label_text="", const std::string &icon_path="", bool toggleable=false, const std::string &checkmark="✓", const std::function< bool(void)> &callback=[] {return true ;}, const std::function< bool(void)> &unchecked_callback=[] {return true ;})
Add a menu in order from the top.
Definition fluent_tray.hpp:906
+
bool set_font(LONG font_size=0, LONG font_weight=0, const std::string &font_name="")
Set font information to draw menus.
Definition fluent_tray.hpp:1260
+
TrayStatus status() const noexcept
Get the current status of tray.
Definition fluent_tray.hpp:1169
+
const FluentMenu & back() const
Returns the const reference to the last of menus.
Definition fluent_tray.hpp:1240
+
bool change_icon(const std::string &icon_path)
Load the image file and change the icon.
Definition fluent_tray.hpp:1402
+
FluentTray()
Create tray object.
Definition fluent_tray.hpp:722
+
std::size_t count_menus() const noexcept
Returns the number of menus.
Definition fluent_tray.hpp:1248
+
bool update_with_loop(std::chrono::milliseconds sleep_time=std::chrono::milliseconds(1))
Create a message loop to update the tray.
Definition fluent_tray.hpp:984
+
std::vector< FluentMenu >::const_iterator cbegin() const noexcept
Returns a constant iterator to the beginning of menus.
Definition fluent_tray.hpp:1200
+
std::vector< FluentMenu >::const_iterator cend() const noexcept
Returns a constant iterator to the end of menus.
Definition fluent_tray.hpp:1208
+
const FluentMenu & front() const
Returns the const reference to the beginning of menus.
Definition fluent_tray.hpp:1224
+
bool set_color(const COLORREF &text_color=CLR_INVALID, const COLORREF &back_color=CLR_INVALID, unsigned char color_decay=10)
Set colors to draw menus.
Definition fluent_tray.hpp:1323
+
void add_separator()
Add a separator line under the last menu item added.
Definition fluent_tray.hpp:929
+
bool hide_menu_window()
Hide the menu window above the tray icon.
Definition fluent_tray.hpp:1119
FluentTray(const FluentTray &)=delete
-
FluentMenu & front()
Returns the reference to the beginning of menus.
Definition fluent_tray.hpp:1208
+
FluentMenu & front()
Returns the reference to the beginning of menus.
Definition fluent_tray.hpp:1216
FluentTray(FluentTray &&)=default
-
HWND window_handle() const noexcept
Refer to the handle of menu window.
Definition fluent_tray.hpp:998
-
std::vector< FluentMenu >::iterator begin() noexcept
Returns an iterator to the beginning of menus.
Definition fluent_tray.hpp:1176
-
bool update()
Get window message and update tray.
Definition fluent_tray.hpp:931
-
FluentMenu & back()
Returns the reference to the last of menus.
Definition fluent_tray.hpp:1224
+
HWND window_handle() const noexcept
Refer to the handle of menu window.
Definition fluent_tray.hpp:1006
+
std::vector< FluentMenu >::iterator begin() noexcept
Returns an iterator to the beginning of menus.
Definition fluent_tray.hpp:1184
+
bool update()
Get window message and update tray.
Definition fluent_tray.hpp:939
+
FluentMenu & back()
Returns the reference to the last of menus.
Definition fluent_tray.hpp:1232
#define FLUENT_TRAY_MESSAGE_ID_OFFSET
Unique message identifier.
Definition fluent_tray.hpp:82
-
bool exists(const std::wstring &path)
Checks if the file exists.
Definition fluent_tray.hpp:231
-
constexpr std::size_t bit2mask(std::size_t bits) noexcept
Generates a mask with the specified number of lower bits set to 1.
Definition fluent_tray.hpp:168
-
bool wstring2string(const std::wstring &wstr, std::string &str)
Converts a wide string to a UTF-8 encoded string.
Definition fluent_tray.hpp:137
-
void concatenate_bits(InType upper, InType lower, OutType &out) noexcept
Generates a variable that combines the bits of two variables.
Definition fluent_tray.hpp:206
-
bool string2wstring(const std::string &str, std::wstring &wstr)
Converts a UTF-8 encoded string to a wide string.
Definition fluent_tray.hpp:106
-
void split_bits(InType input, OutType &upper, OutType &lower) noexcept
Divides the input value into upper and lower bits.
Definition fluent_tray.hpp:190
-
constexpr int type2bit() noexcept
Calculate the number of bits of type.
Definition fluent_tray.hpp:177
-
unsigned char rgb2gray(const COLORREF &rgb)
Calculate grayscale value from RGB.
Definition fluent_tray.hpp:219
+
#define FLUENT_TRAY_COLORPICK_OFFSET
Pixel offset to determine the background color.
Definition fluent_tray.hpp:89
+
bool exists(const std::wstring &path)
Checks if the file exists.
Definition fluent_tray.hpp:239
+
constexpr std::size_t bit2mask(std::size_t bits) noexcept
Generates a mask with the specified number of lower bits set to 1.
Definition fluent_tray.hpp:176
+
bool wstring2string(const std::wstring &wstr, std::string &str)
Converts a wide string to a UTF-8 encoded string.
Definition fluent_tray.hpp:145
+
void concatenate_bits(InType upper, InType lower, OutType &out) noexcept
Generates a variable that combines the bits of two variables.
Definition fluent_tray.hpp:214
+
bool string2wstring(const std::string &str, std::wstring &wstr)
Converts a UTF-8 encoded string to a wide string.
Definition fluent_tray.hpp:114
+
void split_bits(InType input, OutType &upper, OutType &lower) noexcept
Divides the input value into upper and lower bits.
Definition fluent_tray.hpp:198
+
constexpr int type2bit() noexcept
Calculate the number of bits of type.
Definition fluent_tray.hpp:185
+
unsigned char rgb2gray(const COLORREF &rgb)
Calculate grayscale value from RGB.
Definition fluent_tray.hpp:227
Base namespace.
-
TrayStatus
Current tray status.
Definition fluent_tray.hpp:241
+
TrayStatus
Current tray status.
Definition fluent_tray.hpp:249
@ STOPPED
The tray is stopped successfully.
@ RUNNING
The tray is working properly.
@ SHOULD_STOP
The tray is trying to exit successfully.
diff --git a/docs/globals.html b/docs/globals.html index 7a65989..dabf8d9 100644 --- a/docs/globals.html +++ b/docs/globals.html @@ -75,6 +75,7 @@
Here is a list of all file members with links to the files they belong to:
diff --git a/docs/globals_defs.html b/docs/globals_defs.html index 45c9ff6..c363949 100644 --- a/docs/globals_defs.html +++ b/docs/globals_defs.html @@ -75,6 +75,7 @@
Here is a list of all macros with links to the files they belong to:
diff --git a/docs/index.html b/docs/index.html index 52e5d53..0f29727 100644 --- a/docs/index.html +++ b/docs/index.html @@ -77,8 +77,7 @@
fluent-tray
-

-

fluent-tray

+

fluent-tray

@@ -132,8 +131,8 @@

return 0 ;
}
-
Class with information on the entire tray.
Definition fluent_tray.hpp:680
-
bool create_tray(const std::string &app_name, const std::string &icon_path="", LONG menu_x_margin=5, LONG menu_y_margin=5, LONG menu_x_pad=5, LONG menu_y_pad=5, unsigned char opacity=255, bool round_corner=true)
Initialize tray and create icon on tray.
Definition fluent_tray.hpp:765
+
Class with information on the entire tray.
Definition fluent_tray.hpp:688
+
bool create_tray(const std::string &app_name, const std::string &icon_path="", LONG menu_x_margin=5, LONG menu_y_margin=5, LONG menu_x_pad=5, LONG menu_y_pad=5, unsigned char opacity=255, bool round_corner=true)
Initialize tray and create icon on tray.
Definition fluent_tray.hpp:773
Fluent Design-based GUI Library for System Tray Applications.
Base namespace.

diff --git a/docs/search/all_5.js b/docs/search/all_5.js index f9e8794..94dafc3 100644 --- a/docs/search/all_5.js +++ b/docs/search/all_5.js @@ -5,8 +5,9 @@ var searchData= ['fluent_5ftray_2',['fluent_tray',['../namespacefluent__tray.html',1,'']]], ['fluent_5ftray_2ehpp_3',['fluent_tray.hpp',['../fluent__tray_8hpp.html',1,'']]], ['fluent_5ftray_3a_3autil_4',['util',['../namespacefluent__tray_1_1util.html',1,'fluent_tray']]], - ['fluent_5ftray_5fmessage_5fid_5foffset_5',['FLUENT_TRAY_MESSAGE_ID_OFFSET',['../fluent__tray_8hpp.html#a5f249b81cc5c7fbeee48724fbc1ede20',1,'fluent_tray.hpp']]], - ['fluentmenu_6',['FluentMenu',['../classfluent__tray_1_1_fluent_menu.html',1,'fluent_tray::FluentMenu'],['../classfluent__tray_1_1_fluent_menu.html#a55a1de08b1e116b71f2225b76fa1a8ff',1,'fluent_tray::FluentMenu::FluentMenu(bool toggleable=false, const std::function< bool(void)> &callback=[] {return true ;}, const std::function< bool(void)> &unchecked_callback=[] {return true ;})'],['../classfluent__tray_1_1_fluent_menu.html#ae65751fe8b47abcae26e99d2cc092c85',1,'fluent_tray::FluentMenu::FluentMenu(const FluentMenu &)=default'],['../classfluent__tray_1_1_fluent_menu.html#a68503bfb45988babdad9d70be8633698',1,'fluent_tray::FluentMenu::FluentMenu(FluentMenu &&)=default']]], - ['fluenttray_7',['FluentTray',['../classfluent__tray_1_1_fluent_tray.html',1,'fluent_tray::FluentTray'],['../classfluent__tray_1_1_fluent_tray.html#a6a6631acc765ddc89ba36976bbe0175f',1,'fluent_tray::FluentTray::FluentTray()'],['../classfluent__tray_1_1_fluent_tray.html#ac538f9a69ab74ead314a5004f717080f',1,'fluent_tray::FluentTray::FluentTray(const FluentTray &)=delete'],['../classfluent__tray_1_1_fluent_tray.html#adc5d4b971a378080dea22225c0a8e3a1',1,'fluent_tray::FluentTray::FluentTray(FluentTray &&)=default']]], - ['front_8',['front',['../classfluent__tray_1_1_fluent_tray.html#acd10bcf8769e9851026dd1302323cc90',1,'fluent_tray::FluentTray::front()'],['../classfluent__tray_1_1_fluent_tray.html#a974f39be7c66bf61750de98331b063c3',1,'fluent_tray::FluentTray::front() const']]] + ['fluent_5ftray_5fcolorpick_5foffset_5',['FLUENT_TRAY_COLORPICK_OFFSET',['../fluent__tray_8hpp.html#a6cb431e007207f85ae70ab10609a42ce',1,'fluent_tray.hpp']]], + ['fluent_5ftray_5fmessage_5fid_5foffset_6',['FLUENT_TRAY_MESSAGE_ID_OFFSET',['../fluent__tray_8hpp.html#a5f249b81cc5c7fbeee48724fbc1ede20',1,'fluent_tray.hpp']]], + ['fluentmenu_7',['FluentMenu',['../classfluent__tray_1_1_fluent_menu.html',1,'fluent_tray::FluentMenu'],['../classfluent__tray_1_1_fluent_menu.html#a55a1de08b1e116b71f2225b76fa1a8ff',1,'fluent_tray::FluentMenu::FluentMenu(bool toggleable=false, const std::function< bool(void)> &callback=[] {return true ;}, const std::function< bool(void)> &unchecked_callback=[] {return true ;})'],['../classfluent__tray_1_1_fluent_menu.html#ae65751fe8b47abcae26e99d2cc092c85',1,'fluent_tray::FluentMenu::FluentMenu(const FluentMenu &)=default'],['../classfluent__tray_1_1_fluent_menu.html#a68503bfb45988babdad9d70be8633698',1,'fluent_tray::FluentMenu::FluentMenu(FluentMenu &&)=default']]], + ['fluenttray_8',['FluentTray',['../classfluent__tray_1_1_fluent_tray.html',1,'fluent_tray::FluentTray'],['../classfluent__tray_1_1_fluent_tray.html#a6a6631acc765ddc89ba36976bbe0175f',1,'fluent_tray::FluentTray::FluentTray()'],['../classfluent__tray_1_1_fluent_tray.html#ac538f9a69ab74ead314a5004f717080f',1,'fluent_tray::FluentTray::FluentTray(const FluentTray &)=delete'],['../classfluent__tray_1_1_fluent_tray.html#adc5d4b971a378080dea22225c0a8e3a1',1,'fluent_tray::FluentTray::FluentTray(FluentTray &&)=default']]], + ['front_9',['front',['../classfluent__tray_1_1_fluent_tray.html#acd10bcf8769e9851026dd1302323cc90',1,'fluent_tray::FluentTray::front()'],['../classfluent__tray_1_1_fluent_tray.html#a974f39be7c66bf61750de98331b063c3',1,'fluent_tray::FluentTray::front() const']]] ]; diff --git a/docs/search/defines_0.js b/docs/search/defines_0.js index 731c698..193fc60 100644 --- a/docs/search/defines_0.js +++ b/docs/search/defines_0.js @@ -1,4 +1,5 @@ var searchData= [ - ['fluent_5ftray_5fmessage_5fid_5foffset_0',['FLUENT_TRAY_MESSAGE_ID_OFFSET',['../fluent__tray_8hpp.html#a5f249b81cc5c7fbeee48724fbc1ede20',1,'fluent_tray.hpp']]] + ['fluent_5ftray_5fcolorpick_5foffset_0',['FLUENT_TRAY_COLORPICK_OFFSET',['../fluent__tray_8hpp.html#a6cb431e007207f85ae70ab10609a42ce',1,'fluent_tray.hpp']]], + ['fluent_5ftray_5fmessage_5fid_5foffset_1',['FLUENT_TRAY_MESSAGE_ID_OFFSET',['../fluent__tray_8hpp.html#a5f249b81cc5c7fbeee48724fbc1ede20',1,'fluent_tray.hpp']]] ];