]> repos.lx-s.de Git - winmute.git/commitdiff
Added second tray icon to show updates because of Windows' balloon limitations
authorlx-s <lx-s@users.noreply.github.com>
Tue, 19 Dec 2023 15:06:34 +0000 (16:06 +0100)
committerlx-s <lx-s@users.noreply.github.com>
Tue, 19 Dec 2023 15:06:34 +0000 (16:06 +0100)
12 files changed:
WinMute/TrayIcon.cpp
WinMute/TrayIcon.h
WinMute/WinMute.cpp
WinMute/WinMute.h
WinMute/WinMute.rc
WinMute/WinMute.vcxproj
WinMute/WinMute.vcxproj.filters
WinMute/icons/app-update-512.png [new file with mode: 0644]
WinMute/icons/app-update.ico [new file with mode: 0644]
WinMute/icons/app-update.svg [new file with mode: 0644]
WinMute/icons/app.svg
WinMute/resource.h

index 516c314bc037b796dee5de36c7eaa544b03035d5..14de54055b66a9fe7528191f0f6cb76374c0779d 100644 (file)
@@ -40,16 +40,19 @@ TrayIcon::TrayIcon() :
 
 TrayIcon::TrayIcon(
    HWND hWnd, UINT trayID, HICON hIcon,
-   const std::wstring& tooltip, bool show)
-   : initialized_(false), iconVisible_(false)
+   const std::wstring& tooltip, bool show,
+   int callbackId)
+   : initialized_(false), iconVisible_(false), callbackId_(callbackId)
 {
    Init(hWnd, trayID, hIcon, tooltip, show);
 }
 
 void TrayIcon::Init(
    HWND hWnd, UINT trayID, HICON hIcon,
-   const std::wstring& tooltip, bool show)
+   const std::wstring& tooltip, bool show,
+   int callbackId)
 {
+   callbackId_ = callbackId;
    if (!hIcon) {
       hIcon_ = LoadIcon(0, IDI_APPLICATION);
    } else {
@@ -134,8 +137,7 @@ void TrayIcon::ChangeText(const std::wstring& tooltip)
 
 void TrayIcon::ShowPopup(
    const std::wstring& title,
-   const std::wstring& text,
-   int callbackID) const
+   const std::wstring& text) const
 {
    if (!initialized_) {
       TrayIconPopup popup;
@@ -151,10 +153,6 @@ void TrayIcon::ShowPopup(
    tnid.uID = trayID_;
    tnid.uFlags = NIF_INFO | NIF_SHOWTIP;
    tnid.dwInfoFlags = NIIF_INFO | NIIF_NOSOUND | NIIF_LARGE_ICON | NIIF_RESPECT_QUIET_TIME;
-   if (callbackID != 0) {
-      tnid.uCallbackMessage = callbackID;
-      tnid.uFlags |= NIF_MESSAGE;
-   }
    tnid.uTimeout = 10 * 1000;
    StringCchCopy(tnid.szInfoTitle, ARRAY_SIZE(tnid.szInfoTitle), title.c_str());
    StringCchCopy(tnid.szInfo, ARRAY_SIZE(tnid.szInfo), text.c_str());
@@ -179,10 +177,10 @@ bool TrayIcon::AddNotifyIcon()
    tnid.uID = trayID_;
    tnid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE | NIF_SHOWTIP;
    tnid.hIcon = hIcon_;
-   tnid.uCallbackMessage = WM_TRAYICON;
+   tnid.uCallbackMessage = callbackId_;
 
    if (SUCCEEDED(StringCchCopy(tnid.szTip, ARRAY_SIZE(tnid.szTip), tooltip_.c_str()))) {
-      return Shell_NotifyIcon(NIM_ADD, &tnid) != 0;
+      return Shell_NotifyIconW(NIM_ADD, &tnid) != 0;
    }
    return false;
 }
index f5d3d126f97225c24310dfca151682ba7236266a..288234c92f1895abceedee8f549f9fa1b6029800 100644 (file)
@@ -46,10 +46,10 @@ class TrayIcon {
 public:
    TrayIcon();
    TrayIcon(HWND hWnd, UINT trayID, HICON hIcon, const std::wstring& tooltip,
-      bool show);
+      bool show, int callbackId = WM_TRAYICON);
    ~TrayIcon();
    void Init(HWND hWnd, UINT trayID, HICON hIcon, const std::wstring& tooltip,
-      bool show);
+      bool show, int callbackId = WM_TRAYICON);
    void Hide();
    void Show();
    bool IsShown() const noexcept { return iconVisible_; }
@@ -57,8 +57,7 @@ public:
    void ChangeText(const std::wstring& tooltip);
    void ShowPopup(
       const std::wstring& title,
-      const std::wstring& text,
-      int callbackID = 0) const;
+      const std::wstring& text) const;
 
 private:
    void DestroyTrayIcon();
@@ -66,8 +65,10 @@ private:
    bool RemoveNotifyIcon();
    bool ChangeText();
 
+
    mutable std::vector<TrayIconPopup> popupQueue_;
 
+   int callbackId_;
    bool initialized_;
    bool iconVisible_;
    UINT trayID_;
index fa8123bc06d75eeecec940efb39e4c63d5ec39e5..9b987e6d44b1b7a3eaab16795b40a2c110fd1f72 100644 (file)
@@ -164,7 +164,7 @@ bool WinMute::InitAudio()
       return false;
    }
 
-   if (!muteCtrl_.Init(hWnd_, &trayIcon_)) {
+   if (!muteCtrl_.Init(hWnd_, &wmTray_)) {
       return false;
    }
 
@@ -241,7 +241,13 @@ bool WinMute::Init()
       ShowWindowsError(_T("LoadIcon"));
       return false;
    }
-   trayIcon_.Init(hWnd_, 0, hTrayIcon_, L"WinMute", true);
+   hUpdateIcon_ = LoadIconW(hglobInstance, MAKEINTRESOURCE(IDI_APPUPDATE));
+   if (hUpdateIcon_ == nullptr) {
+      ShowWindowsError(_T("LoadIcon"));
+      return false;
+   }
+   wmTray_.Init(hWnd_, 0, hTrayIcon_, L"WinMute", true);
+   updateTray_.Init(hWnd_, 1, hUpdateIcon_, L"WinMute Update", false, WM_WINMUTE_UPDATE_POPUP);
 
    quietHours_.Init(hWnd_, settings_);
 
@@ -249,7 +255,7 @@ bool WinMute::Init()
 
    if (settings_.QueryValue(SettingsKey::MUTE_ON_RDP)
        && IsCurrentSessionRemoteable()) {
-      trayIcon_.ShowPopup(
+      wmTray_.ShowPopup(
          i18n_.GetTranslationW("popup.remote-session-detected.title"),
          i18n_.GetTranslationW("popup.remote-session-detected.text"));
       muteCtrl_.SetMute(true);
@@ -311,7 +317,7 @@ bool WinMute::LoadSettings()
       btDetector_.Unload();
    } else {
       if (!btDetector_.Init(hWnd_)) {
-         trayIcon_.ShowPopup(
+         wmTray_.ShowPopup(
             i18n_.GetTranslationW("popup.bluetooth-muting-disabled.title"),
             i18n_.GetTranslationW("popup.bluetooth-muting-disabled.text"));
          settings_.SetValue(SettingsKey::MUTE_ON_BLUETOOTH, FALSE);
@@ -327,7 +333,7 @@ bool WinMute::LoadSettings()
       wifiDetector_.Unload();
    } else {
       if (!wifiDetector_.Init(hWnd_)) {
-         trayIcon_.ShowPopup(
+         wmTray_.ShowPopup(
             i18n_.GetTranslationW("popup.wlan-muting-disabled.title"),
             i18n_.GetTranslationW("popup.wlan-muting-disabled.text"));
          settings_.SetValue(SettingsKey::MUTE_ON_WLAN, FALSE);
@@ -402,7 +408,7 @@ void WinMute::CheckForUpdatesAsync(std::unique_ptr<UpdateChecker> updateChecker)
       return;
    }
    if (!updateChecker->GetUpdateInfo(updateInfo_)) {
-      trayIcon_.ShowPopup(
+      wmTray_.ShowPopup(
          i18n_.GetTranslationW("popup.error.update-check-failed.title"),
          i18n_.GetTranslationW("popup.error.update-check-failed.text"));
    } else if (updateInfo_.beta.shouldUpdate && betaUpdates) {
@@ -412,7 +418,8 @@ void WinMute::CheckForUpdatesAsync(std::unique_ptr<UpdateChecker> updateChecker)
       const std::wstring popupText = std::vformat(
          i18n_.GetTranslationW("popup.update-available-beta.text"),
          std::make_wformat_args(updateInfo_.currentVersion));
-      trayIcon_.ShowPopup(popupTitle, popupText, WM_WINMUTE_UPDATE_POPUP);
+      updateTray_.Show();
+      updateTray_.ShowPopup(popupTitle, popupText);
    } else if (updateInfo_.beta.shouldUpdate) {
       const std::wstring popupTitle = std::vformat(
          i18n_.GetTranslationW("popup.update-available.title"),
@@ -420,7 +427,8 @@ void WinMute::CheckForUpdatesAsync(std::unique_ptr<UpdateChecker> updateChecker)
       const std::wstring popupText = std::vformat(
          i18n_.GetTranslationW("popup.update-available.text"),
          std::make_wformat_args(updateInfo_.currentVersion));
-      trayIcon_.ShowPopup(popupTitle, popupText, WM_WINMUTE_UPDATE_POPUP);
+      updateTray_.Show();
+      updateTray_.ShowPopup(popupTitle, popupText);
    }
 }
 
@@ -518,10 +526,9 @@ LRESULT WinMute::OnCommand(HWND hWnd, WPARAM wParam, LPARAM)
 
 LRESULT WinMute::OnTrayIcon(HWND hWnd, WPARAM, LPARAM lParam)
 {
-   switch (lParam) {
-   case WM_LBUTTONUP:
-   case WM_RBUTTONUP:
-   {
+   if (LOWORD(lParam) == WM_CONTEXTMENU ||
+       lParam == WM_LBUTTONUP ||
+       lParam == WM_RBUTTONUP) {
       POINT p = { 0 };
       GetCursorPos(&p);
       SetForegroundWindow(hWnd);
@@ -529,10 +536,6 @@ LRESULT WinMute::OnTrayIcon(HWND hWnd, WPARAM, LPARAM lParam)
          GetSubMenu(hTrayMenu_, 0),
          TPM_NONOTIFY | TPM_TOPALIGN | TPM_LEFTALIGN,
          p.x, p.y, hWnd_, nullptr);
-      break;
-   }
-   default:
-      break;
    }
    return TRUE;
 }
@@ -567,7 +570,7 @@ LRESULT WinMute::OnQuietHours(HWND, UINT msg, WPARAM, LPARAM)
    if (msg == WM_WINMUTE_QUIETHOURS_START) {
       muteCtrl_.NotifyQuietHours(true);
       if (settings_.QueryValue(SettingsKey::QUIETHOURS_NOTIFICATIONS)) {
-         trayIcon_.ShowPopup(
+         wmTray_.ShowPopup(
             i18n_.GetTranslationW("popup.quiet-hours-started.title"),
             i18n_.GetTranslationW("popup.quiet-hours-started.text"));
       }
@@ -576,7 +579,7 @@ LRESULT WinMute::OnQuietHours(HWND, UINT msg, WPARAM, LPARAM)
    } else if (msg == WM_WINMUTE_QUIETHOURS_END) {
       muteCtrl_.NotifyQuietHours(false);
       if (settings_.QueryValue(SettingsKey::QUIETHOURS_NOTIFICATIONS)) {
-         trayIcon_.ShowPopup(
+         wmTray_.ShowPopup(
             i18n_.GetTranslationW("popup.quiet-hours-ended.title"),
             i18n_.GetTranslationW("popup.quiet-hours-ended.text"));
       }
@@ -622,7 +625,7 @@ LRESULT WinMute::OnWifiStatusChange(HWND, WPARAM wParam, LPARAM lParam)
             i18n_.GetTranslationW("popup.wlan-is-on-mute-list.text"),
             std::make_wformat_args(wifiName));
       }
-      trayIcon_.ShowPopup(
+      wmTray_.ShowPopup(
          i18n_.GetTranslationW("popup.workstation-muted.title"),
          popupMsg);
       delete[] wifiName;
@@ -646,6 +649,9 @@ LRESULT WinMute::OnUpdatePopup(HWND hWnd, WPARAM, LPARAM lParam)
             nullptr, nullptr, SW_SHOW);
       }
    }
+   if (lParam == NIN_BALLOONHIDE || lParam == NIN_BALLOONTIMEOUT || lParam == NIN_BALLOONUSERCLICK) {
+      updateTray_.Hide();
+   }
    return 0;
 }
 
@@ -701,8 +707,8 @@ LRESULT CALLBACK WinMute::WindowProc(
       return OnSettingChange(hWnd, wParam, lParam);
    default:
       if (msg == uTaskbarRestart) { // Restore trayicon if explorer.exe crashes
-         trayIcon_.Hide();
-         trayIcon_.Show();
+         wmTray_.Hide();
+         wmTray_.Show();
       }
       break;
    }
index 25481c05fa600ca51da1ca9fd27a21b58d328d41..4038e445029655f8f222f64dfb0e403a88a097cc 100644 (file)
@@ -57,6 +57,7 @@ private:
    HMENU hTrayMenu_;
    HICON hAppIcon_;
    HICON hTrayIcon_;
+   HICON hUpdateIcon_;
 
    struct MuteConfig {
       MuteConfig();
@@ -65,7 +66,8 @@ private:
       bool muteOnBluetooth;
    } muteConfig_;
 
-   TrayIcon trayIcon_;
+   TrayIcon wmTray_;
+   TrayIcon updateTray_;
    WifiDetector wifiDetector_;
    WMSettings& settings_;
    WMi18n &i18n_;
index 0a1a12e51f49f86595c15cb4ba8c562280763c26..ffde6c29606cc626a8434b9546495f778451fa9b 100644 (file)
@@ -441,6 +441,8 @@ IDI_APP                 ICON                    "icons\\app.ico"
 
 IDI_SETTINGS            ICON                    "icons\\settings.ico"
 
+IDI_APPUPDATE           ICON                    "icons\\app-update.ico"
+
 
 /////////////////////////////////////////////////////////////////////////////
 //
index 10525f5a55d4db2427eb25f642bfd10eab286eec..34d4712bc458b7659a84497ce646ea1401c934b2 100644 (file)
     <ResourceCompile Include="WinMute.rc" />
   </ItemGroup>
   <ItemGroup>
+    <Image Include="icons\app-update.ico" />
     <Image Include="icons\app.ico" />
     <Image Include="icons\settings.ico" />
   </ItemGroup>
index 7ca23ba510470ea392dd39367e05bc0115175343..ff30cb4720abeaeb6675aa43d3b670cd0c700e03 100644 (file)
     <Image Include="icons\settings.ico">
       <Filter>Resource Files</Filter>
     </Image>
+    <Image Include="icons\app-update.ico">
+      <Filter>Resource Files</Filter>
+    </Image>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="VistaAudio.cpp">
diff --git a/WinMute/icons/app-update-512.png b/WinMute/icons/app-update-512.png
new file mode 100644 (file)
index 0000000..48ec92f
Binary files /dev/null and b/WinMute/icons/app-update-512.png differ
diff --git a/WinMute/icons/app-update.ico b/WinMute/icons/app-update.ico
new file mode 100644 (file)
index 0000000..d282626
Binary files /dev/null and b/WinMute/icons/app-update.ico differ
diff --git a/WinMute/icons/app-update.svg b/WinMute/icons/app-update.svg
new file mode 100644 (file)
index 0000000..fb056ac
--- /dev/null
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   width="512"
+   height="512"
+   viewBox="0 0 512 512"
+   version="1.1"
+   id="svg1"
+   inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
+   sodipodi:docname="app-update.svg"
+   inkscape:export-filename="app-update-512.png"
+   inkscape:export-xdpi="96"
+   inkscape:export-ydpi="96"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <sodipodi:namedview
+     id="namedview1"
+     pagecolor="#505050"
+     bordercolor="#ffffff"
+     borderopacity="1"
+     inkscape:showpageshadow="0"
+     inkscape:pageopacity="0"
+     inkscape:pagecheckerboard="1"
+     inkscape:deskcolor="#505050"
+     inkscape:document-units="px"
+     showguides="true"
+     inkscape:zoom="1.1228082"
+     inkscape:cx="27.164034"
+     inkscape:cy="216.86696"
+     inkscape:window-width="2560"
+     inkscape:window-height="1009"
+     inkscape:window-x="-8"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="layer1">
+    <sodipodi:guide
+       position="-301.02829,261.98278"
+       orientation="0,-1"
+       id="guide8"
+       inkscape:locked="false" />
+    <sodipodi:guide
+       position="-304.59342,361.48454"
+       orientation="0,-1"
+       id="guide9"
+       inkscape:locked="false" />
+    <sodipodi:guide
+       position="-363.37461,162.87538"
+       orientation="0,-1"
+       id="guide10"
+       inkscape:locked="false" />
+    <sodipodi:guide
+       position="-244.92161,460.34381"
+       orientation="0,-1"
+       id="guide11"
+       inkscape:locked="false" />
+    <sodipodi:guide
+       position="-272.53096,62.23486"
+       orientation="0,-1"
+       id="guide12"
+       inkscape:locked="false" />
+    <sodipodi:guide
+       position="50.76557,477.26566"
+       orientation="1,0"
+       id="guide13"
+       inkscape:locked="false" />
+    <sodipodi:guide
+       position="362.48398,358.81267"
+       orientation="1,0"
+       id="guide14"
+       inkscape:locked="false" />
+    <sodipodi:guide
+       position="224.43726,374.8439"
+       orientation="1,0"
+       id="guide15"
+       inkscape:locked="false" />
+    <sodipodi:guide
+       position="314.25338,449.02337"
+       orientation="1,0"
+       id="guide16"
+       inkscape:locked="false" />
+    <sodipodi:guide
+       position="137.1561,394.43763"
+       orientation="1,0"
+       id="guide17"
+       inkscape:locked="false" />
+    <sodipodi:guide
+       position="98.243542,394.2337"
+       orientation="1,0"
+       id="guide18"
+       inkscape:locked="false" />
+    <sodipodi:guide
+       position="299.13899,400.53137"
+       orientation="1,0"
+       id="guide19"
+       inkscape:locked="false" />
+  </sodipodi:namedview>
+  <defs
+     id="defs1">
+    <rect
+       x="391.87458"
+       y="40.968706"
+       width="56.109314"
+       height="357.14024"
+       id="rect26" />
+    <linearGradient
+       id="swatch22">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0.45652175"
+         id="stop22" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#swatch22"
+       id="radialGradient22"
+       cx="206.62624"
+       cy="250.03953"
+       fx="206.62624"
+       fy="250.03953"
+       r="156.80599"
+       gradientTransform="matrix(0.99619803,0,0,1.5243246,0.34028102,-119.52623)"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <g
+     inkscape:label="Ebene 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <path
+       d="m 298.6558,51.763601 -159.39296,100.351939 -89.814619,0.60253 0.728548,195.59663 88.693091,1.65266 158.8987,122.40086 z"
+       style="display:inline;fill:url(#radialGradient22);stroke:#e7e7e7;stroke-width:15;stroke-linecap:round;stroke-linejoin:bevel;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke"
+       id="path26"
+       sodipodi:nodetypes="ccccccc" />
+    <path
+       style="display:inline;fill:#132e3f;fill-opacity:1;stroke:#c0ccf8;stroke-width:8;stroke-dasharray:none;stroke-opacity:1"
+       d="M 447.89768,421.69014 C 235.70893,209.26395 63.39014,45.098196 65.227745,44.931141 L 43.147019,66.306118 421.91096,445.64954 Z"
+       id="path19"
+       inkscape:label="slash"
+       sodipodi:nodetypes="ccccc" />
+    <text
+       xml:space="preserve"
+       id="text26"
+       style="font-size:43.5785px;white-space:pre;shape-inside:url(#rect26);display:none;fill:#122e3f;fill-opacity:1;stroke:#ffffff;stroke-width:1.16262;stroke-linecap:round;stroke-linejoin:bevel;stroke-dasharray:none;stroke-opacity:1;paint-order:markers fill stroke"
+       inkscape:label="Exclamation Mark"
+       transform="matrix(6.992757,0,0,6.7710102,-2420.2895,-308.68022)"><tspan
+         x="391.875"
+         y="81.20562"
+         id="tspan2"><tspan
+           style="font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code'"
+           id="tspan1">!</tspan></tspan></text>
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer2"
+     inkscape:label="Ebene 2">
+    <path
+       style="fill:#27fb86;fill-opacity:0.662136;stroke:#00922d;stroke-width:5.43457;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;paint-order:markers fill stroke"
+       d="m 371.6508,269.07023 c 94.30545,0 94.73608,0 94.73608,0 V 124.9009 h 41.76999 L 412.77487,4.3970993 315.67039,127.07704 h 49.09051 v 141.99319 z"
+       id="path1" />
+  </g>
+</svg>
index beeeee3e5c04dd62be48b0ce462909cd79a541c2..89fe80e06ae4be3168ae7d76594685a6550296c3 100644 (file)
@@ -29,8 +29,8 @@
      inkscape:document-units="px"
      showguides="true"
      inkscape:zoom="1.1228082"
-     inkscape:cx="18.257793"
-     inkscape:cy="217.75758"
+     inkscape:cx="26.27341"
+     inkscape:cy="216.86696"
      inkscape:window-width="2560"
      inkscape:window-height="1009"
      inkscape:window-x="-8"
        transform="matrix(6.992757,0,0,6.7710102,-2420.2895,-308.68022)"><tspan
          x="391.875"
          y="81.20562"
-         id="tspan2"><tspan
+         id="tspan4"><tspan
            style="font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code'"
-           id="tspan1">!</tspan></tspan></text>
+           id="tspan3">!</tspan></tspan></text>
   </g>
 </svg>
index cac11632c0cb4b5ddb03d8c6bb9f44bcaa41e8b5..fd045896746f5b6100661fcee5b58242d867bf21 100644 (file)
@@ -23,6 +23,8 @@
 #define IDD_MANAGE_ENDPOINTS            135
 #define IDD_DIALOG2                     137
 #define IDD_MANAGE_ENDPOINTS_ADD        137
+#define IDI_APP_UPDATE                  141
+#define IDI_APPUPDATE                   141
 #define IDC_LINK_HOMEPAGE               1001
 #define IDC_LINK_SUPPORT                1002
 #define IDC_LINK_PROJECT                1002
@@ -45,7 +47,6 @@
 #define IDC_CHECK_FOR_UPDATES_ON_STARTUP 1013
 #define IDC_OPENLOG                     1014
 #define IDC_LICENSETEXT                 1015
-#define IDC_CHECK_FOR_UPDATES_ON_STARTUP2 1015
 #define IDC_CHECK_FOR_BETA_UPDATES      1015
 #define IDC_ABOUT_TAB                   1016
 #define IDC_ABOUTTEXT                   1019
 // 
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        141
+#define _APS_NEXT_RESOURCE_VALUE        142
 #define _APS_NEXT_COMMAND_VALUE         40041
 #define _APS_NEXT_CONTROL_VALUE         1072
 #define _APS_NEXT_SYMED_VALUE           101