[STOBJECT]
authorEric Kohl <eric.kohl@reactos.org>
Fri, 18 Aug 2017 14:49:11 +0000 (14:49 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Fri, 18 Aug 2017 14:49:11 +0000 (14:49 +0000)
- Add support for the hotplug icon.
- Set default menu items in the context menus.
- Use a timer to properly distinguish between a single and a double click on an icon.
- Some code cleanup.

svn path=/trunk/; revision=75611

reactos/dll/shellext/stobject/CMakeLists.txt
reactos/dll/shellext/stobject/csystray.cpp
reactos/dll/shellext/stobject/hotplug.cpp [new file with mode: 0644]
reactos/dll/shellext/stobject/power.cpp
reactos/dll/shellext/stobject/precomp.h
reactos/dll/shellext/stobject/stobject.cpp
reactos/dll/shellext/stobject/volume.cpp

index dc1d02e..2fa34e6 100644 (file)
@@ -21,6 +21,7 @@ add_library(stobject SHARED
     csystray.cpp
     stobject.cpp
     stobject.rc
+    hotplug.cpp
     power.cpp
     volume.cpp
     ${CMAKE_CURRENT_BINARY_DIR}/stobject.def)
index 6200254..8551fbc 100644 (file)
@@ -12,6 +12,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(stobject);
 
 SysTrayIconHandlers_t g_IconHandlers [] = {
         { Volume_Init, Volume_Shutdown, Volume_Update, Volume_Message },
+        { Hotplug_Init, Hotplug_Shutdown, Hotplug_Update, Hotplug_Message },
         { Power_Init, Power_Shutdown, Power_Update, Power_Message }
 };
 const int g_NumIcons = _countof(g_IconHandlers);
@@ -211,13 +212,37 @@ BOOL CSysTray::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
     case WM_NCCREATE:
     case WM_NCDESTROY:
         return FALSE;
+
     case WM_CREATE:
         InitIcons();
         SetTimer(1, 2000, NULL);
         return TRUE;
+
     case WM_TIMER:
-        UpdateIcons();
-        return TRUE;
+        switch (wParam)
+        {
+            case 1:
+                UpdateIcons();
+                return TRUE;
+
+            case POWER_TIMER_ID:
+                Power_OnTimer(hWnd);
+                break;
+
+            case VOLUME_TIMER_ID:
+                Volume_OnTimer(hWnd);
+                break;
+
+            case HOTPLUG_TIMER_ID:
+                Hotplug_OnTimer(hWnd);
+                break;
+        }
+        break;
+
+    case WM_DEVICECHANGE:
+        ERR("WM_DEVICECHANGE\n");
+        break;
+
     case WM_DESTROY:
         KillTimer(1);
         ShutdownIcons();
diff --git a/reactos/dll/shellext/stobject/hotplug.cpp b/reactos/dll/shellext/stobject/hotplug.cpp
new file mode 100644 (file)
index 0000000..fbc22ea
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * PROJECT:     ReactOS system libraries
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        dll/shellext/stobject/hotplug.cpp
+ * PURPOSE:     Hotplug notification icon handler
+ * PROGRAMMERS: Eric Kohl <eric.kohl@reactos.org>
+ *              David Quintana <gigaherz@gmail.com>
+ */
+
+#include "precomp.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(stobject);
+
+static HICON g_hIconHotplug = NULL;
+static BOOL g_IsRunning = FALSE;
+
+
+HRESULT STDMETHODCALLTYPE Hotplug_Init(_In_ CSysTray * pSysTray)
+{
+    WCHAR strTooltip[128];
+
+    TRACE("Hotplug_Init\n");
+
+    g_hIconHotplug = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_EXTRACT));
+
+    LoadStringW(g_hInstance, IDS_HOTPLUG_REMOVE_1, strTooltip, _countof(strTooltip));
+
+    g_IsRunning = TRUE;
+
+    return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_HOTPLUG, g_hIconHotplug, strTooltip);
+}
+
+HRESULT STDMETHODCALLTYPE Hotplug_Update(_In_ CSysTray * pSysTray)
+{
+    TRACE("Hotplug_Update\n");
+    return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE Hotplug_Shutdown(_In_ CSysTray * pSysTray)
+{
+    TRACE("Hotplug_Shutdown\n");
+
+    g_IsRunning = FALSE;
+
+    return pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_HOTPLUG, NULL, NULL);
+}
+
+static void RunHotplug()
+{
+    ShellExecuteW(NULL, NULL, L"rundll32.exe", L"shell32.dll,Control_RunDLL hotplug.dll", NULL, SW_SHOWNORMAL);
+}
+
+static void ShowContextMenu(CSysTray *pSysTray)
+{
+    WCHAR szBuffer[128];
+    DWORD id, msgPos;
+    HMENU hPopup;
+
+    LoadStringW(g_hInstance, IDS_HOTPLUG_REMOVE_2, szBuffer, _countof(szBuffer));
+
+    hPopup = CreatePopupMenu();
+    AppendMenuW(hPopup, MF_STRING, 1, szBuffer);
+
+    msgPos = GetMessagePos();
+
+    SetForegroundWindow(pSysTray->GetHWnd());
+    id = TrackPopupMenuEx(hPopup,
+                          TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN,
+                          GET_X_LPARAM(msgPos),
+                          GET_Y_LPARAM(msgPos),
+                          pSysTray->GetHWnd(),
+                          NULL);
+
+    DestroyMenu(hPopup);
+
+    if (id == 1)
+        RunHotplug();
+}
+
+static
+VOID
+ShowHotplugPopupMenu(
+    HWND hWnd)
+{
+#if 0
+    DWORD id, msgPos;
+
+    HMENU hPopup = CreatePopupMenu();
+
+    // FIXME
+    AppendMenuW(hPopup, MF_STRING, IDS_VOL_OPEN, strOpen);
+
+    msgPos = GetMessagePos();
+
+    SetForegroundWindow(hWnd);
+    id = TrackPopupMenuEx(hPopup,
+                          TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN,
+                          GET_X_LPARAM(msgPos),
+                          GET_Y_LPARAM(msgPos),
+                          hWnd,
+                          NULL);
+
+    DestroyMenu(hPopup);
+
+    if (id != 0)
+    {
+        // FIXME
+    }
+#endif
+}
+
+HRESULT STDMETHODCALLTYPE Hotplug_Message(_In_ CSysTray *pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult)
+{
+    TRACE("Hotplug_Message uMsg=%d, wParam=%x, lParam=%x\n", uMsg, wParam, lParam);
+
+    switch (uMsg)
+    {
+        case WM_USER + 220:
+            TRACE("Hotplug_Message: WM_USER+220\n");
+            if (wParam == 2)
+            {
+                if (lParam == FALSE)
+                    return Hotplug_Init(pSysTray);
+                else
+                    return Hotplug_Shutdown(pSysTray);
+            }
+            return S_FALSE;
+
+        case WM_USER + 221:
+            TRACE("Hotplug_Message: WM_USER+221\n");
+            if (wParam == 2)
+            {
+                lResult = (LRESULT)g_IsRunning;
+                return S_OK;
+            }
+            return S_FALSE;
+
+        case ID_ICON_HOTPLUG:
+            Hotplug_Update(pSysTray);
+
+            switch (lParam)
+            {
+                case WM_LBUTTONDOWN:
+                    SetTimer(pSysTray->GetHWnd(), HOTPLUG_TIMER_ID, 500, NULL);
+                    break;
+
+                case WM_LBUTTONUP:
+                    break;
+
+                case WM_LBUTTONDBLCLK:
+                    KillTimer(pSysTray->GetHWnd(), HOTPLUG_TIMER_ID);
+                    RunHotplug();
+                    break;
+
+                case WM_RBUTTONDOWN:
+                    break;
+
+                case WM_RBUTTONUP:
+                    ShowContextMenu(pSysTray);
+                    break;
+
+                case WM_RBUTTONDBLCLK:
+                    break;
+
+                case WM_MOUSEMOVE:
+                    break;
+            }
+            return S_OK;
+
+        default:
+            TRACE("Hotplug_Message received for unknown ID %d, ignoring.\n");
+            return S_FALSE;
+    }
+
+    return S_FALSE;
+}
+
+VOID
+Hotplug_OnTimer(HWND hWnd)
+{
+    TRACE("Hotplug_OnTimer\n!");
+    KillTimer(hWnd, HOTPLUG_TIMER_ID);
+    ShowHotplugPopupMenu(hWnd);
+}
index c36bedd..24b5feb 100644 (file)
 #include "precomp.h"
 #include "powrprof.h"
 
-#include <mmsystem.h>
-#include <mmddk.h>
-
-#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
-#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
-
 WINE_DEFAULT_DEBUG_CHANNEL(stobject);
 
 typedef struct _PWRSCHEMECONTEXT
@@ -25,9 +19,7 @@ typedef struct _PWRSCHEMECONTEXT
     UINT uiLast;
 } PWRSCHEMECONTEXT, *PPWRSCHEMECONTEXT;
 
-//static HICON g_hIconBattery = NULL;
-static HICON g_hIconAC = NULL;
-
+static HICON g_hIconBattery = NULL;
 static BOOL g_IsRunning = FALSE;
 
 
@@ -37,53 +29,18 @@ HRESULT STDMETHODCALLTYPE Power_Init(_In_ CSysTray * pSysTray)
 
     TRACE("Power_Init\n");
 
-//    g_hIconBattery = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_BATTERY));
-    g_hIconAC = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_BATTERY));
-
-
-    HICON icon;
-//    if (g_IsMute)
-//        icon = g_hIconBattery;
-//    else
-        icon = g_hIconAC;
+    g_hIconBattery = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_BATTERY));
 
     LoadStringW(g_hInstance, IDS_PWR_AC, strTooltip, _countof(strTooltip));
 
     g_IsRunning = TRUE;
 
-    return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_POWER, icon, strTooltip);
+    return pSysTray->NotifyIcon(NIM_ADD, ID_ICON_POWER, g_hIconBattery, strTooltip);
 }
 
 HRESULT STDMETHODCALLTYPE Power_Update(_In_ CSysTray * pSysTray)
 {
-//    BOOL PrevState;
-
     TRACE("Power_Update\n");
-
-#if 0
-    PrevState = g_IsMute;
-    Volume_IsMute();
-
-    if (PrevState != g_IsMute)
-    {
-        WCHAR strTooltip[128];
-        HICON icon;
-        if (g_IsMute) {
-            icon = g_hIconMute;
-            LoadStringW(g_hInstance, IDS_VOL_MUTED, strTooltip, _countof(strTooltip));
-        }
-        else {
-            icon = g_hIconVolume;
-            LoadStringW(g_hInstance, IDS_VOL_VOLUME, strTooltip, _countof(strTooltip));
-        }
-
-        return pSysTray->NotifyIcon(NIM_MODIFY, ID_ICON_POWER, icon, strTooltip);
-    }
-    else
-    {
-        return S_OK;
-    }
-#endif
     return S_OK;
 }
 
@@ -96,36 +53,37 @@ HRESULT STDMETHODCALLTYPE Power_Shutdown(_In_ CSysTray * pSysTray)
     return pSysTray->NotifyIcon(NIM_DELETE, ID_ICON_POWER, NULL, NULL);
 }
 
-static void _RunPower()
+static void RunPower()
 {
-    ShellExecuteW(NULL, NULL, L"powercfg.cpl", NULL, NULL, SW_SHOWNORMAL);
+    ShellExecuteW(NULL, NULL, L"rundll32.exe", L"shell32.dll,Control_RunDLL powercfg.cpl", NULL, SW_SHOWNORMAL);
 }
 
-static void _ShowContextMenu(CSysTray * pSysTray)
+static void ShowContextMenu(CSysTray * pSysTray)
 {
-    WCHAR strOpen[128];
+    WCHAR szBuffer[128];
+    DWORD id, msgPos;
+    HMENU hPopup;
 
-    LoadStringW(g_hInstance, IDS_PWR_PROPERTIES, strOpen, _countof(strOpen));
+    LoadStringW(g_hInstance, IDS_PWR_PROPERTIES, szBuffer, _countof(szBuffer));
 
-    HMENU hPopup = CreatePopupMenu();
-    AppendMenuW(hPopup, MF_STRING, IDS_PWR_PROPERTIES, strOpen);
+    hPopup = CreatePopupMenu();
+    AppendMenuW(hPopup, MF_STRING, IDS_PWR_PROPERTIES, szBuffer);
+    SetMenuDefaultItem(hPopup, IDS_PWR_PROPERTIES, FALSE);
 
-    DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN;
-    DWORD msgPos = GetMessagePos();
+    msgPos = GetMessagePos();
 
     SetForegroundWindow(pSysTray->GetHWnd());
-    DWORD id = TrackPopupMenuEx(hPopup, flags,
-        GET_X_LPARAM(msgPos), GET_Y_LPARAM(msgPos),
-        pSysTray->GetHWnd(), NULL);
+    id = TrackPopupMenuEx(hPopup,
+                          TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN,
+                          GET_X_LPARAM(msgPos),
+                          GET_Y_LPARAM(msgPos),
+                          pSysTray->GetHWnd(),
+                          NULL);
 
     DestroyMenu(hPopup);
 
-    switch (id)
-    {
-        case IDS_PWR_PROPERTIES:
-            _RunPower();
-            break;
-    }
+    if (id == IDS_PWR_PROPERTIES)
+        RunPower();
 }
 
 static
@@ -156,7 +114,7 @@ PowerSchemesEnumProc(
 static
 VOID
 ShowPowerSchemesPopupMenu(
-    CSysTray *pSysTray)
+    HWND hWnd)
 {
     PWRSCHEMECONTEXT PowerSchemeContext = {NULL, 0, 0};
     UINT uiActiveScheme;
@@ -176,12 +134,12 @@ ShowPowerSchemesPopupMenu(
 
     msgPos = GetMessagePos();
 
-    SetForegroundWindow(pSysTray->GetHWnd());
+    SetForegroundWindow(hWnd);
     id = TrackPopupMenuEx(PowerSchemeContext.hPopup,
                           TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN,
                           GET_X_LPARAM(msgPos),
                           GET_Y_LPARAM(msgPos),
-                          pSysTray->GetHWnd(),
+                          hWnd,
                           NULL);
 
     DestroyMenu(PowerSchemeContext.hPopup);
@@ -222,21 +180,22 @@ HRESULT STDMETHODCALLTYPE Power_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPA
             switch (lParam)
             {
                 case WM_LBUTTONDOWN:
+                    SetTimer(pSysTray->GetHWnd(), POWER_TIMER_ID, 500, NULL);
                     break;
 
                 case WM_LBUTTONUP:
-                    ShowPowerSchemesPopupMenu(pSysTray);
                     break;
 
                 case WM_LBUTTONDBLCLK:
-                    _RunPower();
+                    KillTimer(pSysTray->GetHWnd(), POWER_TIMER_ID);
+                    RunPower();
                     break;
 
                 case WM_RBUTTONDOWN:
                     break;
 
                 case WM_RBUTTONUP:
-                    _ShowContextMenu(pSysTray);
+                    ShowContextMenu(pSysTray);
                     break;
 
                 case WM_RBUTTONDBLCLK:
@@ -254,3 +213,11 @@ HRESULT STDMETHODCALLTYPE Power_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPA
 
     return S_FALSE;
 }
+
+VOID
+Power_OnTimer(HWND hWnd)
+{
+    TRACE("Power_OnTimer\n!");
+    KillTimer(hWnd, POWER_TIMER_ID);
+    ShowPowerSchemesPopupMenu(hWnd);
+}
index 66790be..fd2ea78 100644 (file)
 
 extern HINSTANCE g_hInstance;
 
-#define ID_ICON_VOLUME (WM_APP + 0x4CB)
-#define ID_ICON_POWER  (WM_APP + 0x4CC)
+#define ID_ICON_VOLUME  (WM_APP + 0x4CB)
+#define ID_ICON_HOTPLUG (WM_APP + 0x4CC)
+#define ID_ICON_POWER   (WM_APP + 0x4CD)
+
+#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
+#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
 
 #include "csystray.h"
 
@@ -65,8 +69,20 @@ extern HRESULT STDMETHODCALLTYPE Volume_Init(_In_ CSysTray * pSysTray);
 extern HRESULT STDMETHODCALLTYPE Volume_Shutdown(_In_ CSysTray * pSysTray);
 extern HRESULT STDMETHODCALLTYPE Volume_Update(_In_ CSysTray * pSysTray);
 extern HRESULT STDMETHODCALLTYPE Volume_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult);
+extern VOID Volume_OnTimer(HWND hWnd);
+
+extern HRESULT STDMETHODCALLTYPE Hotplug_Init(_In_ CSysTray * pSysTray);
+extern HRESULT STDMETHODCALLTYPE Hotplug_Shutdown(_In_ CSysTray * pSysTray);
+extern HRESULT STDMETHODCALLTYPE Hotplug_Update(_In_ CSysTray * pSysTray);
+extern HRESULT STDMETHODCALLTYPE Hotplug_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult);
+extern VOID Hotplug_OnTimer(HWND hWnd);
 
 extern HRESULT STDMETHODCALLTYPE Power_Init(_In_ CSysTray * pSysTray);
 extern HRESULT STDMETHODCALLTYPE Power_Shutdown(_In_ CSysTray * pSysTray);
 extern HRESULT STDMETHODCALLTYPE Power_Update(_In_ CSysTray * pSysTray);
 extern HRESULT STDMETHODCALLTYPE Power_Message(_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult);
+extern VOID Power_OnTimer(HWND hWnd);
+
+#define POWER_TIMER_ID   2
+#define VOLUME_TIMER_ID  3
+#define HOTPLUG_TIMER_ID 4
\ No newline at end of file
index fc866f3..f5b31e2 100644 (file)
@@ -4,7 +4,7 @@
  * FILE:        dll/shellext/stobject/stobject.cpp
  * PURPOSE:     COM registration services for STobject.dll
  * PROGRAMMERS: Robert Naumann
- David Quintana <gigaherz@gmail.com>
*              David Quintana <gigaherz@gmail.com>
  */
 
 #include "precomp.h"
index f848468..f82e6e0 100644 (file)
@@ -11,9 +11,6 @@
 #include <mmsystem.h>
 #include <mmddk.h>
 
-#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
-#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
-
 WINE_DEFAULT_DEBUG_CHANNEL(stobject);
 
 HICON g_hIconVolume;
@@ -116,7 +113,7 @@ static HRESULT __stdcall Volume_FindMixerControl(CSysTray * pSysTray)
     return S_OK;
 }
 
-HRESULT Volume_IsMute()
+HRESULT Volume_IsMute(VOID)
 {
 #if 0
     MIXERCONTROLDETAILS mixerControlDetails;
@@ -220,10 +217,10 @@ HRESULT Volume_OnDeviceChange(_In_ CSysTray * pSysTray, WPARAM wParam, LPARAM lP
     return Volume_FindMixerControl(pSysTray);
 }
 
-static void _RunVolume()
+static void _RunVolume(BOOL bSmall)
 {
     // FIXME: ensure we are loading the right one
-    ShellExecuteW(NULL, NULL, L"sndvol32.exe", NULL, NULL, SW_SHOWNORMAL);
+    ShellExecuteW(NULL, NULL, L"sndvol32.exe", bSmall ? L"/t" : NULL, NULL, SW_SHOWNORMAL);
 }
 
 static void _RunMMCpl()
@@ -241,6 +238,7 @@ static void _ShowContextMenu(CSysTray * pSysTray)
     HMENU hPopup = CreatePopupMenu();
     AppendMenuW(hPopup, MF_STRING, IDS_VOL_OPEN, strOpen);
     AppendMenuW(hPopup, MF_STRING, IDS_VOL_ADJUST, strAdjust);
+    SetMenuDefaultItem(hPopup, IDS_VOL_OPEN, FALSE);
 
     DWORD flags = TPM_RETURNCMD | TPM_NONOTIFY | TPM_RIGHTALIGN | TPM_BOTTOMALIGN;
     DWORD msgPos = GetMessagePos();
@@ -255,7 +253,7 @@ static void _ShowContextMenu(CSysTray * pSysTray)
     switch (id)
     {
     case IDS_VOL_OPEN:
-        _RunVolume();
+        _RunVolume(FALSE);
         break;
     case IDS_VOL_ADJUST:
         _RunMMCpl();
@@ -298,14 +296,15 @@ HRESULT STDMETHODCALLTYPE Volume_Message(_In_ CSysTray * pSysTray, UINT uMsg, WP
             switch (lParam)
             {
                 case WM_LBUTTONDOWN:
+                    SetTimer(pSysTray->GetHWnd(), VOLUME_TIMER_ID, 500, NULL);
                     break;
 
                 case WM_LBUTTONUP:
-                    TRACE("TODO: display volume slider\n");
                     break;
 
                 case WM_LBUTTONDBLCLK:
-                    _RunVolume();
+                    KillTimer(pSysTray->GetHWnd(), VOLUME_TIMER_ID);
+                    _RunVolume(FALSE);
                     break;
 
                 case WM_RBUTTONDOWN:
@@ -330,3 +329,11 @@ HRESULT STDMETHODCALLTYPE Volume_Message(_In_ CSysTray * pSysTray, UINT uMsg, WP
 
     return S_FALSE;
 }
+
+VOID
+Volume_OnTimer(HWND hWnd)
+{
+    TRACE("Volume_OnTimer\n!");
+    KillTimer(hWnd, VOLUME_TIMER_ID);
+    _RunVolume(TRUE);
+}