+
+
1130 const COLORREF& text_color=CLR_INVALID,
+
1131 const COLORREF& back_color=CLR_INVALID,
+
1132 unsigned char color_decay=10) {
+
1133 if(back_color == CLR_INVALID) {
+
+
+
1136 abd.cbSize =
sizeof(abd) ;
+
1137 if(!SHAppBarMessage(ABM_GETTASKBARPOS, &abd)) {
+
+
+
+
1141 if(
auto dc = GetDC(NULL)) {
+
+
1143 back_color_ = GetPixel(dc, abd.rc.left + 1, abd.rc.top + 1) ;
+
1144 if(back_color_ == CLR_INVALID) {
+
+
1146 back_color_ = GetSysColor(COLOR_WINDOW) ;
+
+
1148 if(!ReleaseDC(NULL, dc)) {
+
+
+
+
+
+
1154 back_color_ = back_color ;
+
+
+
+
+
1159 unsigned char ash_value = back_gray_color_ ;
+
1160 if(back_gray_color_ < 128) {
+
1161 ash_value =
static_cast<decltype(ash_value)
>(
+
1162 (std::min)(ash_value + color_decay, 255)) ;
+
+
+
1165 ash_value =
static_cast<decltype(ash_value)
>(
+
1166 (std::max)(ash_value - color_decay, 0)) ;
+
+
1168 ash_color_ = RGB(ash_value, ash_value, ash_value) ;
+
+
1170 if(text_color == CLR_INVALID) {
+
1171 text_color_ = GetSysColor(COLOR_WINDOWTEXT) ;
+
1172 if(back_gray_color_ < 128) {
+
+
1174 text_color_ = 0x00FFFFFF & ~text_color_ ;
+
+
+
+
1178 text_color_ = text_color ;
+
+
+
+
+
1183 if(!DeleteObject(back_brush_)) {
+
+
+
+
1187 back_brush_ = CreateSolidBrush(back_color_) ;
+
1188 if(back_brush_ == NULL) {
+
+
+
+
1192 if(!SetClassLongPtr(
+
1193 hwnd_, GCLP_HBRBACKGROUND,
+
1194 reinterpret_cast<LONG_PTR
>(back_brush_))) {
+
+
+
+
+
-
-
1205 if(icon_data_.cbSize > 0) {
-
1206 if(!Shell_NotifyIconW(NIM_DELETE, &icon_data_)) {
-
-
-
-
-
1211 ZeroMemory(&icon_data_,
sizeof(icon_data_)) ;
-
-
1213 if(icon_path.empty()) {
-
1214 icon_data_.cbSize = 0 ;
-
-
-
-
1218 std::wstring icon_path_wide ;
-
-
-
-
-
-
-
-
-
1227 icon_data_.cbSize =
sizeof(icon_data_) ;
-
1228 icon_data_.hWnd = hwnd_ ;
-
1229 icon_data_.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP ;
-
1230 icon_data_.uCallbackMessage = MESSAGE_ID ;
-
1231 icon_data_.hIcon =
static_cast<HICON
>(
-
-
1233 NULL, icon_path_wide.c_str(),
-
1234 IMAGE_ICON, 0, 0, LR_LOADFROMFILE)) ;
-
1235 wcscpy_s(icon_data_.szTip, app_name_.c_str()) ;
-
1236 icon_data_.dwState = NIS_SHAREDICON ;
-
1237 icon_data_.dwStateMask = NIS_SHAREDICON ;
-
-
1239 if(!Shell_NotifyIconW(NIM_ADD, &icon_data_)) {
-
-
-
-
-
-
+
+
+
+
1206 if(icon_data_.cbSize > 0) {
+
1207 if(!Shell_NotifyIconW(NIM_DELETE, &icon_data_)) {
+
+
+
+
+
1212 ZeroMemory(&icon_data_,
sizeof(icon_data_)) ;
+
+
1214 if(icon_path.empty()) {
+
1215 icon_data_.cbSize = 0 ;
+
+
+
+
1219 std::wstring icon_path_wide ;
+
+
+
+
+
+
+
+
+
1228 icon_data_.cbSize =
sizeof(icon_data_) ;
+
1229 icon_data_.hWnd = hwnd_ ;
+
1230 icon_data_.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP ;
+
1231 icon_data_.uCallbackMessage = MESSAGE_ID ;
+
1232 icon_data_.hIcon =
static_cast<HICON
>(
+
+
1234 NULL, icon_path_wide.c_str(),
+
1235 IMAGE_ICON, 0, 0, LR_LOADFROMFILE)) ;
+
1236 wcscpy_s(icon_data_.szTip, app_name_.c_str()) ;
+
1237 icon_data_.dwState = NIS_SHAREDICON ;
+
1238 icon_data_.dwStateMask = NIS_SHAREDICON ;
+
+
1240 if(!Shell_NotifyIconW(NIM_ADD, &icon_data_)) {
+
+
+
+
+
+
-
-
-
1248 static LRESULT CALLBACK callback(
-
-
-
-
-
1253 auto get_instance = [hwnd]() {
-
1254 auto upper_addr = GetWindowLongW(hwnd, 0) ;
-
-
1256 return reinterpret_cast<FluentTray*
>(
nullptr) ;
-
-
-
1259 auto lower_addr = GetWindowLongW(hwnd,
sizeof(LONG)) ;
-
-
1261 return reinterpret_cast<FluentTray*
>(
nullptr) ;
-
-
-
-
-
-
-
-
1269 if(msg == WM_DESTROY || msg == WM_QUIT || msg == WM_CLOSE) {
-
1270 if(
auto self = get_instance()) {
-
-
-
-
-
1275 else if(msg == WM_ACTIVATE && wparam == WA_INACTIVE) {
-
1276 if(
auto self = get_instance()) {
-
1277 if(!self->hide_menu_window()) {
-
-
-
-
-
-
1283 else if(msg == WM_DRAWITEM) {
-
1284 if(
auto self = get_instance()) {
-
1285 auto item =
reinterpret_cast<LPDRAWITEMSTRUCT
>(lparam) ;
-
1286 auto menu_idx = self->get_menu_index_from_window(item->hwndItem) ;
-
-
-
-
1290 auto& menu = self->menus_[menu_idx] ;
-
1291 if(!menu.draw_menu(item, self->font_)) {
-
-
-
-
-
-
-
1298 else if(msg == WM_CTLCOLORBTN) {
-
1299 if(
auto self = get_instance()) {
-
1300 auto menu_idx = self->get_menu_index_from_window(
reinterpret_cast<HWND
>(lparam)) ;
-
-
1302 return DefWindowProc(hwnd, msg, wparam, lparam) ;
-
-
1304 auto& menu = self->menus_[menu_idx] ;
-
1305 return reinterpret_cast<LRESULT
>(menu.background_brush()) ;
-
-
-
1308 else if(msg == WM_COMMAND) {
-
1309 if(
auto self = get_instance()) {
-
1310 auto menu_idx = self->get_menu_index_from_id(LOWORD(wparam)) ;
-
-
-
-
1314 auto& menu = self->menus_[menu_idx] ;
-
1315 if(!menu.process_click_event()) {
-
-
-
-
1319 if(menu.toggleable()) {
-
-
1321 if(!InvalidateRect(menu.window_handle(), NULL, TRUE)) {
-
-
-
-
-
-
-
1328 else if(msg == MESSAGE_ID) {
-
1329 if(
auto self = get_instance()) {
-
1330 if(lparam == WM_LBUTTONUP || lparam == WM_RBUTTONUP) {
-
1331 self->show_menu_window() ;
-
-
-
-
-
-
1337 return DefWindowProc(hwnd, msg, wparam, lparam) ;
-
-
-
1340 int get_menu_index_from_window(HWND hwnd) {
-
-
1342 for(
auto& m : menus_) {
-
1343 if(m.window_handle() == hwnd) {
-
-
-
-
-
-
-
-
1351 int get_menu_index_from_id(WORD
id) {
-
-
1353 for(
auto& m : menus_) {
-
1354 if(m.id() ==
static_cast<std::size_t
>(
id)) {
-
-
-
-
-
-
-
-
1362 void get_message(MSG& message) {
-
1363 if(PeekMessage(&message, hwnd_, 0, 0, PM_REMOVE)) {
-
1364 DispatchMessage(&message) ;
-
-
-
-
1368 void fail() noexcept {
-
-
-
-
1372 bool change_menu_back_color(FluentMenu& menu, COLORREF new_color) {
-
-
1374 text_color_, new_color, ash_color_)) {
-
-
-
-
1378 if(!InvalidateRect(menu.window_handle(), NULL, TRUE)) {
-
-
-
-
-
+
+
+
1249 static LRESULT CALLBACK callback(
+
+
+
+
+
1254 auto get_instance = [hwnd]() {
+
1255 auto upper_addr = GetWindowLongW(hwnd, 0) ;
+
+
1257 return reinterpret_cast<FluentTray*
>(
nullptr) ;
+
+
+
1260 auto lower_addr = GetWindowLongW(hwnd,
sizeof(LONG)) ;
+
+
1262 return reinterpret_cast<FluentTray*
>(
nullptr) ;
+
+
+
+
+
+
+
+
1270 if(msg == WM_DESTROY || msg == WM_QUIT || msg == WM_CLOSE) {
+
1271 if(
auto self = get_instance()) {
+
+
+
+
+
1276 else if(msg == WM_ACTIVATE && wparam == WA_INACTIVE) {
+
1277 if(
auto self = get_instance()) {
+
1278 if(!self->hide_menu_window()) {
+
+
+
+
+
+
1284 else if(msg == WM_DRAWITEM) {
+
1285 if(
auto self = get_instance()) {
+
1286 auto item =
reinterpret_cast<LPDRAWITEMSTRUCT
>(lparam) ;
+
1287 auto menu_idx = self->get_menu_index_from_window(item->hwndItem) ;
+
+
+
+
1291 auto& menu = self->menus_[menu_idx] ;
+
1292 if(!menu.draw_menu(item, self->font_)) {
+
+
+
+
+
+
+
1299 else if(msg == WM_CTLCOLORBTN) {
+
1300 if(
auto self = get_instance()) {
+
1301 auto menu_idx = self->get_menu_index_from_window(
reinterpret_cast<HWND
>(lparam)) ;
+
+
1303 return DefWindowProc(hwnd, msg, wparam, lparam) ;
+
+
1305 auto& menu = self->menus_[menu_idx] ;
+
1306 return reinterpret_cast<LRESULT
>(menu.background_brush()) ;
+
+
+
1309 else if(msg == WM_COMMAND) {
+
1310 if(
auto self = get_instance()) {
+
1311 auto menu_idx = self->get_menu_index_from_id(LOWORD(wparam)) ;
+
+
+
+
1315 auto& menu = self->menus_[menu_idx] ;
+
1316 if(!menu.process_click_event()) {
+
+
+
+
1320 if(menu.toggleable()) {
+
+
1322 if(!InvalidateRect(menu.window_handle(), NULL, TRUE)) {
+
+
+
+
+
+
+
1329 else if(msg == MESSAGE_ID) {
+
1330 if(
auto self = get_instance()) {
+
1331 if(lparam == WM_LBUTTONUP || lparam == WM_RBUTTONUP) {
+
1332 self->show_menu_window() ;
+
+
+
+
+
+
1338 return DefWindowProc(hwnd, msg, wparam, lparam) ;
+
+
+
1341 int get_menu_index_from_window(HWND hwnd) {
+
+
1343 for(
auto& m : menus_) {
+
1344 if(m.window_handle() == hwnd) {
+
+
+
+
+
+
+
+
1352 int get_menu_index_from_id(WORD
id) {
+
+
1354 for(
auto& m : menus_) {
+
1355 if(m.id() ==
static_cast<std::size_t
>(
id)) {
+
+
+
+
+
+
+
+
1363 void get_message(MSG& message) {
+
1364 if(PeekMessage(&message, hwnd_, 0, 0, PM_REMOVE)) {
+
1365 DispatchMessage(&message) ;
+
+
+
+
1369 void fail() noexcept {
+
+
+
+
1373 bool change_menu_back_color(FluentMenu& menu, COLORREF new_color) {
+
+
1375 text_color_, new_color, ash_color_)) {
+
+
+
+
1379 if(!InvalidateRect(menu.window_handle(), NULL, TRUE)) {
+
+
+
+
+
diff --git a/include/fluent_tray.hpp b/include/fluent_tray.hpp
index 1c5abe6..138e36a 100644
--- a/include/fluent_tray.hpp
+++ b/include/fluent_tray.hpp
@@ -247,7 +247,7 @@ namespace fluent_tray
* @brief Create menu object.
* @param [in] toggleable Create a switchable menu
* @param [in] callback Function called when a click on the menu or a check is enabled.
- * @param [in] unchecked_callback Function called when a check is distabled.
+ * @param [in] unchecked_callback Function called when a check is disabled.
* @details The callback function must be a function with a bool return value and no arguments. The tray will exit successfully if the callback function returns false.
*/
explicit FluentMenu(
@@ -714,15 +714,15 @@ namespace fluent_tray
}
/**
- * @brief Initialize tray and create icon on tray
- * @param [in] app_name
- * @param [in] icon_path
- * @param [in] menu_x_margin
- * @param [in] menu_y_margin
- * @param [in] menu_x_pad
- * @param [in] menu_y_pad
- * @param [in] opacity
- * @param [in] round_corner
+ * @brief Initialize tray and create icon on tray.
+ * @param [in] app_name The application name to be displayed as tooltip text.
+ * @param [in] icon_path A UTF-8 encoded path to the icon to be displayed in the system tray.
+ * @param [in] menu_x_margin Horizontal margins outside menus.
+ * @param [in] menu_y_margin Vertical margins outside menus.
+ * @param [in] menu_x_pad Horizontal paddings inside menus.
+ * @param [in] menu_y_pad Vertical paddings inside menus.
+ * @param [in] opacity Menu opacity from 0 to 255.
+ * @param [in] round_corner Option to round the corners of the menu window (Windows 11 only)
* @return Returns true on success, false on failure.
*/
bool create_tray(
@@ -818,12 +818,12 @@ namespace fluent_tray
/**
* @brief Add a menu in order from the top.
- * @param [in] label_text
- * @param [in] icon_path
- * @param [in] toggleable
- * @param [in] checkmark
- * @param [in] callback
- * @param [in] unchecked_callback
+ * @param [in] label_text The UTF-8 encoded string of the button label.
+ * @param [in] icon_path An icon path to show next to the label.
+ * @param [in] toggleable Create a switchable menu
+ * @param [in] checkmark A checkmark string.
+ * @param [in] callback Function called when a click on the menu or a check is enabled.
+ * @param [in] unchecked_callback Function called when a check is disabled.
* @return Returns true on success, false on failure.
*/
bool add_menu(
@@ -1059,10 +1059,11 @@ namespace fluent_tray
/**
* @brief Set font information to draw menus.
- * @param [in] font_size
- * @param [in] font_weight
- * @param [in] font_name
+ * @param [in] font_size The height of fonts.
+ * @param [in] font_weight The value from 0 to 1000 to determine font weight.
+ * @param [in] font_name The UTF-8 encoded font name for label rendering.
* @return Returns true on success, false on failure.
+ * @details For font_weight, you can use the constant value specified for lfWeght in
. The default value used is FW_MEDIUM(500).
*/
bool set_font(
LONG font_size=0,
@@ -1120,9 +1121,9 @@ namespace fluent_tray
/**
* @brief Set colors to draw menus.
- * @param [in] text_color
- * @param [in] back_color
- * @param [in] color_decay
+ * @param [in] text_color The color for label text.
+ * @param [in] back_color The color for background.
+ * @param [in] color_decay Decay value from the background color to determine the background color of the currently selected menu and the color of the separator line.
* @return Returns true on success, false on failure.
*/
bool set_color(