[STOBJECT] Improvements to the power notification icon
authorEric Kohl <eric.kohl@reactos.org>
Fri, 19 Apr 2019 19:50:13 +0000 (21:50 +0200)
committerEric Kohl <eric.kohl@reactos.org>
Fri, 19 Apr 2019 19:54:37 +0000 (21:54 +0200)
- Use GetSystemPowerStatus() instead of querying each battery.
- Add an ugly AC power icon. Should be fixed or replaced.
- Display AC power, battery charging, battery depleting and error cases. The AC power case was missing.
- Update some strings because we are no longer using float for the charge percentage.

@Turkish translators: Please check and update the translation of IDS_PWR_CHARGING!

17 files changed:
dll/shellext/stobject/lang/cs-CZ.rc
dll/shellext/stobject/lang/de-DE.rc
dll/shellext/stobject/lang/en-US.rc
dll/shellext/stobject/lang/es-ES.rc
dll/shellext/stobject/lang/fr-FR.rc
dll/shellext/stobject/lang/hi-IN.rc
dll/shellext/stobject/lang/it-IT.rc
dll/shellext/stobject/lang/pl-PL.rc
dll/shellext/stobject/lang/ro-RO.rc
dll/shellext/stobject/lang/ru-RU.rc
dll/shellext/stobject/lang/tr-TR.rc
dll/shellext/stobject/lang/zh-CN.rc
dll/shellext/stobject/lang/zh-TW.rc
dll/shellext/stobject/power.cpp
dll/shellext/stobject/resource.h
dll/shellext/stobject/resources/battery/ac.ico [new file with mode: 0644]
dll/shellext/stobject/stobject.rc

index 57ec1bc..34d63c3 100644 (file)
@@ -18,8 +18,8 @@ BEGIN
     IDS_PWR_PROPERTIES        "&Upravit možnosti napájení"
     IDS_PWR_METER             "&Otevřít ukazatel spotřeby"
     IDS_PWR_RUN               "shell32.dll,Control_RunDLL PowerCfg.cpl"
-    IDS_PWR_PERCENT_REMAINING "zbývá %.2f%%"
-    IDS_PWR_CHARGING          "%.2f%% and charging"
+    IDS_PWR_PERCENT_REMAINING "zbývá %u%%"
+    IDS_PWR_CHARGING          "%u%% and charging"
     IDS_PWR_UNKNOWN_REMAINING "Zbývá neznámo"
     IDS_PWR_AC "On AC power"
     IDS_PWR_HOURS_REMAINING "zbývá %1!u!:%2!02u! hodin (%3!u!%%)"
index 7d0657d..5363c29 100644 (file)
@@ -18,8 +18,8 @@ BEGIN
     IDS_PWR_PROPERTIES        "&Energieverwaltungseigenschaften einstellen"
     IDS_PWR_METER             "Batterieanzeige ö&ffnen"
     IDS_PWR_RUN               "shell32.dll,Control_RunDLL PowerCfg.cpl"
-    IDS_PWR_PERCENT_REMAINING "%.2f%% verbleibend"
-    IDS_PWR_CHARGING          "%.2f%% und wird geladen"
+    IDS_PWR_PERCENT_REMAINING "%u%% verbleibend"
+    IDS_PWR_CHARGING          "%u%% und wird geladen"
     IDS_PWR_UNKNOWN_REMAINING "Unbekannt verbleibend"
     IDS_PWR_AC "Mit Wechselstrom"
     IDS_PWR_HOURS_REMAINING "%1!u!:%2!02u! Stunden (%3!u!%%) verbleibend"
index ea1f17f..807fd93 100644 (file)
@@ -18,8 +18,8 @@ BEGIN
     IDS_PWR_PROPERTIES        "&Adjust Power Properties"
     IDS_PWR_METER             "&Open Power Meter"
     IDS_PWR_RUN               "shell32.dll,Control_RunDLL PowerCfg.cpl"
-    IDS_PWR_PERCENT_REMAINING "%.2f%% remaining"
-    IDS_PWR_CHARGING          "%.2f%% and charging"
+    IDS_PWR_PERCENT_REMAINING "%u%% remaining"
+    IDS_PWR_CHARGING          "%u%% and charging"
     IDS_PWR_UNKNOWN_REMAINING "Unknown remaining"
     IDS_PWR_AC "On AC power"
     IDS_PWR_HOURS_REMAINING "%1!u!:%2!02u! hours (%3!u!%%) remaining"
index 3da6c8f..623412f 100644 (file)
@@ -19,8 +19,8 @@ BEGIN
     IDS_PWR_PROPERTIES        "&Ajustar propiedades de energía"
     IDS_PWR_METER             "Abrir &medidor de energía"
     IDS_PWR_RUN               "shell32.dll,Control_RunDLL PowerCfg.cpl"
-    IDS_PWR_PERCENT_REMAINING "Queda un %.2f%%"
-    IDS_PWR_CHARGING          "%.2f%% y cargando"
+    IDS_PWR_PERCENT_REMAINING "Queda un %u%%"
+    IDS_PWR_CHARGING          "%u%% y cargando"
     IDS_PWR_UNKNOWN_REMAINING "Estado de batería desconocido"
     IDS_PWR_AC "En corriente alterna"
     IDS_PWR_HOURS_REMAINING "Quedan %1!u!:%2!02u! horas (%3!u!%%)"
index de393af..f0dfd9d 100644 (file)
@@ -18,8 +18,8 @@ BEGIN
     IDS_PWR_PROPERTIES        "&Adjust Power Properties"
     IDS_PWR_METER             "&Open Power Meter"
     IDS_PWR_RUN               "shell32.dll,Control_RunDLL PowerCfg.cpl"
-    IDS_PWR_PERCENT_REMAINING "%.2f%% remaining"
-    IDS_PWR_CHARGING          "%.2f%% and charging"
+    IDS_PWR_PERCENT_REMAINING "%u%% remaining"
+    IDS_PWR_CHARGING          "%u%% and charging"
     IDS_PWR_UNKNOWN_REMAINING "Unknown remaining"
     IDS_PWR_AC "On AC power"
     IDS_PWR_HOURS_REMAINING "%1!u!:%2!02u! hours (%3!u!%%) remaining"
index 0abe3e5..6b4b56f 100644 (file)
@@ -25,8 +25,8 @@ BEGIN
     IDS_PWR_PROPERTIES        "पावर &गुण समायोजित करें"
     IDS_PWR_METER             "पावर मीटर &खोलें"
     IDS_PWR_RUN               "shell32.dll,Control_RunDLL PowerCfg.cpl"
-    IDS_PWR_PERCENT_REMAINING "%.2f%% शेष"
-    IDS_PWR_CHARGING          "%.2f%% और चार्ज"
+    IDS_PWR_PERCENT_REMAINING "%u%% शेष"
+    IDS_PWR_CHARGING          "%u%% और चार्ज"
     IDS_PWR_UNKNOWN_REMAINING "अज्ञात शेष"
     IDS_PWR_AC "On AC power"
     IDS_PWR_HOURS_REMAINING "%1!u!:%2!02u! घंटे (%3!u!%%) शेष"
index 628466e..e6fb7a3 100644 (file)
@@ -18,8 +18,8 @@ BEGIN
     IDS_PWR_PROPERTIES        "&Modifica proprietà alimentazione"
     IDS_PWR_METER             "&Apri misuratore alimentazione"
     IDS_PWR_RUN               "shell32.dll,Control_RunDLL PowerCfg.cpl"
-    IDS_PWR_PERCENT_REMAINING "%.2f%% rimanenti"
-    IDS_PWR_CHARGING          "%.2f%% and charging"
+    IDS_PWR_PERCENT_REMAINING "%u%% rimanenti"
+    IDS_PWR_CHARGING          "%u%% and charging"
     IDS_PWR_UNKNOWN_REMAINING "Autonomia sconosciuta"
     IDS_PWR_AC                "Alimentazione da rete AC"
     IDS_PWR_HOURS_REMAINING   "%1!u!:%2!02u! ore (%3!u!%%) rimanenti"
index 3f1cc8d..74649a0 100644 (file)
@@ -18,8 +18,8 @@ BEGIN
     IDS_PWR_PROPERTIES        "&Opcje zasilania"
     IDS_PWR_METER             "&Otwórz miernik baterii"
     IDS_PWR_RUN               "shell32.dll,Control_RunDLL PowerCfg.cpl"
-    IDS_PWR_PERCENT_REMAINING "Pozostało %.2f%%"
-    IDS_PWR_CHARGING          "%.2f%% i ładuje"
+    IDS_PWR_PERCENT_REMAINING "Pozostało %u%%"
+    IDS_PWR_CHARGING          "%u%% i ładuje"
     IDS_PWR_UNKNOWN_REMAINING "Stan naładowania nieznany"
     IDS_PWR_AC "Podłączony do zasilania"
     IDS_PWR_HOURS_REMAINING "Pozostało %1!u!:%2!02u! godzin (%3!u!%%)"
index abbf38b..b06b3e4 100644 (file)
@@ -20,8 +20,8 @@ BEGIN
     IDS_PWR_PROPERTIES        "&Ajustare proprietăți de consum energie"
     IDS_PWR_METER             "&Deschide Contor de energie"
     IDS_PWR_RUN               "shell32.dll,Control_RunDLL PowerCfg.cpl"
-    IDS_PWR_PERCENT_REMAINING "Au mai rămas %.2f%%"
-    IDS_PWR_CHARGING          "%.2f%% and charging"
+    IDS_PWR_PERCENT_REMAINING "Au mai rămas %u%%"
+    IDS_PWR_CHARGING          "%u%% and charging"
     IDS_PWR_UNKNOWN_REMAINING "Nu este disponibil cât a mai rămas"
     IDS_PWR_AC "În rețea de CA"
     IDS_PWR_HOURS_REMAINING "Au mai rămas %1!u!:%2!02u! ore (%3!u!%%)"
index af307d3..07fae4b 100644 (file)
@@ -20,8 +20,8 @@ BEGIN
     IDS_PWR_PROPERTIES        "&Настройка параметров электропитания"
     IDS_PWR_METER             "&Открыть показатели питания"
     IDS_PWR_RUN               "shell32.dll,Control_RunDLL PowerCfg.cpl"
-    IDS_PWR_PERCENT_REMAINING "%.2f%% осталось"
-    IDS_PWR_CHARGING          "%.2f%% and charging"
+    IDS_PWR_PERCENT_REMAINING "%u%% осталось"
+    IDS_PWR_CHARGING          "%u%% and charging"
     IDS_PWR_UNKNOWN_REMAINING "Неизвестно"
     IDS_PWR_AC "От сети переменного тока"
     IDS_PWR_HOURS_REMAINING "%1!u!:%2!02u! часов (%3!u!%%) осталось"
index 6fa7816..2aa1f9b 100644 (file)
@@ -20,8 +20,8 @@ BEGIN
     IDS_PWR_PROPERTIES        "&Güç Özelliklerini Düzenle"
     IDS_PWR_METER             "G&üç Ölçücüsünü Aç"
     IDS_PWR_RUN               "shell32.dll,Control_RunDLL PowerCfg.cpl"
-    IDS_PWR_PERCENT_REMAINING "%%%1!u! kaldı."
-    IDS_PWR_CHARGING          " (Yükleniyor)"
+    IDS_PWR_PERCENT_REMAINING "%%%u kaldı."
+    IDS_PWR_CHARGING          "%%%u (Yükleniyor)"
     IDS_PWR_UNKNOWN_REMAINING "Bilinmeyen kalan."
     IDS_PWR_AC "Dalgalı akımda."
     IDS_PWR_HOURS_REMAINING "%1!u!.%2!02u! saat (%%%3!u!) kalan"
index b75b267..0589656 100644 (file)
@@ -20,8 +20,8 @@ BEGIN
     IDS_PWR_PROPERTIES        "调整电源属性(&A)"
     IDS_PWR_METER             "开放式电源表(&O)"
     IDS_PWR_RUN               "shell32.dll,Control_RunDLL PowerCfg.cpl"
-    IDS_PWR_PERCENT_REMAINING "剩余 %.2f%%"
-    IDS_PWR_CHARGING          "%.2f%% and charging"
+    IDS_PWR_PERCENT_REMAINING "剩余 %u%%"
+    IDS_PWR_CHARGING          "%u%% and charging"
     IDS_PWR_UNKNOWN_REMAINING "未知剩余"
     IDS_PWR_AC "交流电源"
     IDS_PWR_HOURS_REMAINING "%1!u!:%2!02u! 小时 剩余 (%3!u!%%) "
index 001cf84..af6e90e 100644 (file)
@@ -20,8 +20,8 @@ BEGIN
     IDS_PWR_PROPERTIES        "調整電源屬性(&A)"
     IDS_PWR_METER             "開放式電源表(&O)"
     IDS_PWR_RUN               "shell32.dll,Control_RunDLL PowerCfg.cpl"
-    IDS_PWR_PERCENT_REMAINING "剩餘 %.2f%%"
-    IDS_PWR_CHARGING          "%.2f%% and charging"
+    IDS_PWR_PERCENT_REMAINING "剩餘 %u%%"
+    IDS_PWR_CHARGING          "%u%% and charging"
     IDS_PWR_UNKNOWN_REMAINING "未知剩餘"
     IDS_PWR_AC "交流電源"
     IDS_PWR_HOURS_REMAINING "%1!u!:%2!02u! 小時 剩餘 (%3!u!%%) "
index 24d5fd8..347fb01 100644 (file)
@@ -16,9 +16,6 @@
 #include <windows.h>
 #include <batclass.h>
 
-#define GBS_HASBATTERY 0x1
-#define GBS_ONBATTERY  0x2
-
 int br_icons[5] = { IDI_BATTCAP0, IDI_BATTCAP1, IDI_BATTCAP2, IDI_BATTCAP3, IDI_BATTCAP4 }; // battery mode icons.
 int bc_icons[5] = { IDI_BATTCHA0, IDI_BATTCHA1, IDI_BATTCHA2, IDI_BATTCHA3, IDI_BATTCHA4 }; // charging mode icons.
 
@@ -30,126 +27,9 @@ typedef struct _PWRSCHEMECONTEXT
 } PWRSCHEMECONTEXT, *PPWRSCHEMECONTEXT;
 
 CString  g_strTooltip;
-static float g_batCap = 0;
 static HICON g_hIconBattery = NULL;
 static BOOL g_IsRunning = FALSE;
 
-/*++
-* @name GetBatteryState
-*
-* Enumerates the available battery devices and provides the remaining capacity.
-*
-* @param cap
-*        If no error occurs, then this will contain average remaining capacity.
-* @param dwResult
-*        Helps in making battery type checks.
-*       {
-*           Returned value includes GBS_HASBATTERY if the system has a non-UPS battery,
-*           and GBS_ONBATTERY if the system is running on a battery.
-*           dwResult & GBS_ONBATTERY means we have not yet found AC power.
-*           dwResult & GBS_HASBATTERY means we have found a non-UPS battery.
-*       }
-*
-* @return The error code.
-*
-*--*/
-static HRESULT GetBatteryState(float& cap, DWORD& dwResult)
-{
-    cap = 0;
-    dwResult = GBS_ONBATTERY;
-
-    HDEVINFO hdev = SetupDiGetClassDevs(&GUID_DEVCLASS_BATTERY, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
-    if (INVALID_HANDLE_VALUE == hdev)
-        return E_HANDLE;
-
-    // Limit search to 100 batteries max
-    for (int idev = 0, count = 0; idev < 100; idev++)
-    {
-        SP_DEVICE_INTERFACE_DATA did = { 0 };
-        did.cbSize = sizeof(did);
-
-        if (SetupDiEnumDeviceInterfaces(hdev, 0, &GUID_DEVCLASS_BATTERY, idev, &did))
-        {
-            DWORD cbRequired = 0;
-
-            SetupDiGetDeviceInterfaceDetail(hdev, &did, 0, 0, &cbRequired, 0);
-            if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
-            {
-                PSP_DEVICE_INTERFACE_DETAIL_DATA pdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, cbRequired);
-                if (pdidd)
-                {
-                    pdidd->cbSize = sizeof(*pdidd);
-                    if (SetupDiGetDeviceInterfaceDetail(hdev, &did, pdidd, cbRequired, &cbRequired, 0))
-                    {
-                        // Enumerated a battery.  Ask it for information.
-                        HANDLE hBattery = CreateFile(pdidd->DevicePath, GENERIC_READ | GENERIC_WRITE,
-                            FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-
-                        if (INVALID_HANDLE_VALUE != hBattery)
-                        {
-                            // Ask the battery for its tag.
-                            BATTERY_QUERY_INFORMATION bqi = { 0 };
-
-                            DWORD dwWait = 0;
-                            DWORD dwOut;
-
-                            if (DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_TAG, &dwWait, sizeof(dwWait), &bqi.BatteryTag,
-                                sizeof(bqi.BatteryTag), &dwOut, NULL) && bqi.BatteryTag)
-                            {
-                                // With the tag, you can query the battery info.
-                                BATTERY_INFORMATION bi = { 0 };
-                                bqi.InformationLevel = BatteryInformation;
-
-                                if (DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_INFORMATION, &bqi, sizeof(bqi), &bi,
-                                    sizeof(bi), &dwOut, NULL))
-                                {
-                                    // Only non-UPS system batteries count
-                                    if (bi.Capabilities & BATTERY_SYSTEM_BATTERY)
-                                    {
-                                        if (!(bi.Capabilities & BATTERY_IS_SHORT_TERM))
-                                            dwResult |= GBS_HASBATTERY;
-
-                                        // Query the battery status.
-                                        BATTERY_WAIT_STATUS bws = { 0 };
-                                        bws.BatteryTag = bqi.BatteryTag;
-
-                                        BATTERY_STATUS bs;
-                                        if (DeviceIoControl(hBattery, IOCTL_BATTERY_QUERY_STATUS, &bws, sizeof(bws),
-                                            &bs, sizeof(bs), &dwOut, NULL))
-                                        {
-                                            if (bs.PowerState & BATTERY_POWER_ON_LINE)
-                                                dwResult &= ~GBS_ONBATTERY;
-
-                                            // Take average of total capacity of batteries detected!
-                                            cap = cap*(count)+(float)bs.Capacity / bi.FullChargedCapacity * 100;
-                                            cap /= count + 1;
-                                            count++;
-                                        }
-                                    }
-                                }
-                            }
-                            CloseHandle(hBattery);
-                        }
-                    }
-                    LocalFree(pdidd);
-                }
-            }
-        }
-        else  if (ERROR_NO_MORE_ITEMS == GetLastError())
-        {
-            break;  // Enumeration failed - perhaps we're out of items
-        }
-    }
-    SetupDiDestroyDeviceInfoList(hdev);
-
-    //  Final cleanup:  If we didn't find a battery, then presume that we
-    //  are on AC power.
-
-    if (!(dwResult & GBS_HASBATTERY))
-        dwResult &= ~GBS_ONBATTERY;
-
-    return S_OK;
-}
 
 /*++
 * @name Quantize
@@ -158,23 +38,9 @@ static HRESULT GetBatteryState(float& cap, DWORD& dwResult)
 * 
 * @param p
 *        Should be a quantity in percentage.
-* @param lvl
-*        Quantization level (this excludes base level 0, which will always be present), default is 10.
 *
 * @return Nearest quantized level, can be directly used as array index based on context.
 *
-*--*/
-static UINT Quantize(float p, UINT lvl = 10)
-{
-    int i = 0;
-    float f, q = (float)100 / lvl, d = q / 2;
-    for (f = 0; f < p; f += q, i++);
-
-    if ((f - d) <= p)
-        return i;
-    else
-        return i - 1;
-/* 
  @remarks This function uses centred/symmetric logic for quantization.
  For the case of lvl = 4, You will get following integer levels if given (p) value falls in between the range partitions:
      0    <= p <  12.5 : returns 0; (corresponding to 0% centre)
@@ -182,7 +48,19 @@ static UINT Quantize(float p, UINT lvl = 10)
      37.5 <= p <  62.5 : returns 2; (corresponding to 50% centre)
      62.5 <= p <  87.5 : returns 3; (corresponding to 75% centre)
      87.5 <= p <= 100  : returns 4; (corresponding to 100% centre)
-*/
+ *--*/
+static UINT Quantize(BYTE p)
+{
+    if (p <= 12)
+        return 0;
+    else if (p > 12 && p <= 37)
+        return 1;
+    else if (p > 37 && p <= 62)
+        return 2;
+    else if (p > 62 && p <= 87)
+        return 3;
+    else
+        return 4;
 }
 
 /*++
@@ -198,35 +76,38 @@ static UINT Quantize(float p, UINT lvl = 10)
 *
 *--*/
 static HICON DynamicLoadIcon(HINSTANCE hinst)
-{    
+{
+    SYSTEM_POWER_STATUS PowerStatus;
     HICON hBatIcon;
-    float cap = 0;
-    DWORD dw = 0;
     UINT index = -1;
-    HRESULT hr = GetBatteryState(cap, dw);
 
-    if (!FAILED(hr) && (dw & GBS_HASBATTERY))
-    {
-        index = Quantize(cap, 4);
-        g_batCap = cap;
-    }
-    else
+    if (!GetSystemPowerStatus(&PowerStatus) ||
+        PowerStatus.ACLineStatus == AC_LINE_UNKNOWN ||
+        PowerStatus.BatteryFlag == BATTERY_FLAG_UNKNOWN)
     {
-        g_batCap = 0;
         hBatIcon = LoadIcon(hinst, MAKEINTRESOURCE(IDI_BATTCAP_ERR));
         g_strTooltip.LoadStringW(IDS_PWR_UNKNOWN_REMAINING);
         return hBatIcon;
     }
 
-    if (dw & GBS_ONBATTERY)
+    if (((PowerStatus.BatteryFlag & BATTERY_FLAG_NO_BATTERY) == 0) &&
+        ((PowerStatus.BatteryFlag & BATTERY_FLAG_CHARGING) == BATTERY_FLAG_CHARGING))
     {
+        index = Quantize(PowerStatus.BatteryLifePercent);
+        hBatIcon = LoadIcon(hinst, MAKEINTRESOURCE(bc_icons[index])); 
+        g_strTooltip.Format(IDS_PWR_CHARGING, PowerStatus.BatteryLifePercent);
+    }
+    else if (((PowerStatus.BatteryFlag & BATTERY_FLAG_NO_BATTERY) == 0) &&
+             ((PowerStatus.BatteryFlag & BATTERY_FLAG_CHARGING) == 0))
+    {
+        index = Quantize(PowerStatus.BatteryLifePercent);
         hBatIcon = LoadIcon(hinst, MAKEINTRESOURCE(br_icons[index]));
-        g_strTooltip.Format(IDS_PWR_PERCENT_REMAINING, cap);
+        g_strTooltip.Format(IDS_PWR_PERCENT_REMAINING, PowerStatus.BatteryLifePercent);
     }
     else
     {
-        hBatIcon = LoadIcon(hinst, MAKEINTRESOURCE(bc_icons[index])); 
-        g_strTooltip.Format(IDS_PWR_CHARGING, cap);
+        hBatIcon = LoadIcon(hinst, MAKEINTRESOURCE(IDI_POWER_AC));
+        g_strTooltip.LoadStringW(IDS_PWR_AC);
     }
 
     return hBatIcon;
index a7466f7..71d500e 100644 (file)
@@ -51,6 +51,7 @@
 #define IDI_BATTCHA3              409
 #define IDI_BATTCHA4              410
 #define IDI_BATTCAP_ERR           412
+#define IDI_POWER_AC              413
 
 #define IDI_HOTPLUG_ERR           420
 #define IDI_HOTPLUG_OK            421
diff --git a/dll/shellext/stobject/resources/battery/ac.ico b/dll/shellext/stobject/resources/battery/ac.ico
new file mode 100644 (file)
index 0000000..b10bb47
Binary files /dev/null and b/dll/shellext/stobject/resources/battery/ac.ico differ
index 5946127..0540b5a 100644 (file)
@@ -25,6 +25,7 @@ IDI_BATTCHA3 ICON "resources/battery/charging3.ico"
 IDI_BATTCHA4 ICON "resources/battery/charging4.ico"
 
 IDI_BATTCAP_ERR ICON "resources/battery/error.ico"
+IDI_POWER_AC ICON "resources/battery/ac.ico"
 
 IDI_HOTPLUG_ERR ICON "resources/hotplug/0.ico"
 IDI_HOTPLUG_OK ICON  "resources/hotplug/1.ico"