mirror of
https://github.com/reactos/reactos.git
synced 2025-05-01 19:50:36 +00:00
[STOBJECT]
* Improve code organization. * Add some debug prints. * Fix some nits. svn path=/branches/shell-experiments/; revision=63787
This commit is contained in:
parent
149d0f17d3
commit
cd1e4d2911
7 changed files with 411 additions and 331 deletions
|
@ -27,6 +27,7 @@ static int CALLBACK InitializeAllCallback(void* pItem, void* pData)
|
||||||
{
|
{
|
||||||
IOleCommandTarget * pOct = pItem;
|
IOleCommandTarget * pOct = pItem;
|
||||||
HRESULT * phr = pData;
|
HRESULT * phr = pData;
|
||||||
|
DbgPrint("Initializing SSO %p\n", pOct);
|
||||||
*phr = IOleCommandTarget_Exec(pOct, &CGID_ShellServiceObject, OLECMDID_NEW, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
|
*phr = IOleCommandTarget_Exec(pOct, &CGID_ShellServiceObject, OLECMDID_NEW, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
|
||||||
return SUCCEEDED(*phr);
|
return SUCCEEDED(*phr);
|
||||||
}
|
}
|
||||||
|
@ -34,6 +35,7 @@ static int CALLBACK InitializeAllCallback(void* pItem, void* pData)
|
||||||
static int CALLBACK ShutdownAllCallback(void* pItem, void* pData)
|
static int CALLBACK ShutdownAllCallback(void* pItem, void* pData)
|
||||||
{
|
{
|
||||||
IOleCommandTarget * pOct = pItem;
|
IOleCommandTarget * pOct = pItem;
|
||||||
|
DbgPrint("Shutting down SSO %p\n", pOct);
|
||||||
IOleCommandTarget_Exec(pOct, &CGID_ShellServiceObject, OLECMDID_SAVE, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
|
IOleCommandTarget_Exec(pOct, &CGID_ShellServiceObject, OLECMDID_SAVE, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -41,6 +43,7 @@ static int CALLBACK ShutdownAllCallback(void* pItem, void* pData)
|
||||||
static int CALLBACK DeleteAllEnumCallback(void* pItem, void* pData)
|
static int CALLBACK DeleteAllEnumCallback(void* pItem, void* pData)
|
||||||
{
|
{
|
||||||
IOleCommandTarget * pOct = pItem;
|
IOleCommandTarget * pOct = pItem;
|
||||||
|
DbgPrint("Releasing SSO %p\n", pOct);
|
||||||
IUnknown_Release(pOct);
|
IUnknown_Release(pOct);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -60,10 +63,13 @@ HRESULT InitShellServices(HDPA * phdpa)
|
||||||
|
|
||||||
hdpa = DPA_Create(5);
|
hdpa = DPA_Create(5);
|
||||||
|
|
||||||
|
DbgPrint("Enumerating Shell Service Ojbect GUIDs...\n");
|
||||||
|
|
||||||
if (RegOpenKey(HKEY_LOCAL_MACHINE,
|
if (RegOpenKey(HKEY_LOCAL_MACHINE,
|
||||||
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad",
|
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad",
|
||||||
&hkey))
|
&hkey))
|
||||||
{
|
{
|
||||||
|
DbgPrint("ERROR: RegOpenKey failed.\n");
|
||||||
return HRESULT_FROM_WIN32(GetLastError());
|
return HRESULT_FROM_WIN32(GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,15 +84,24 @@ HRESULT InitShellServices(HDPA * phdpa)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (type != REG_SZ)
|
if (type != REG_SZ)
|
||||||
|
{
|
||||||
|
DbgPrint("WARNING: Value type was not REG_SZ.\n");
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
hr = CLSIDFromString(value, &clsid);
|
hr = CLSIDFromString(value, &clsid);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
DbgPrint("ERROR: CLSIDFromString failed %08x.\n", hr);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IOleCommandTarget, (VOID**) &pOct);
|
hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IOleCommandTarget, (VOID**) &pOct);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
DbgPrint("ERROR: CoCreateInstance failed %08x.\n", hr);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
DPA_AppendPtr(hdpa, pOct);
|
DPA_AppendPtr(hdpa, pOct);
|
||||||
|
|
||||||
|
@ -96,6 +111,7 @@ HRESULT InitShellServices(HDPA * phdpa)
|
||||||
|
|
||||||
if (ret != ERROR_NO_MORE_ITEMS)
|
if (ret != ERROR_NO_MORE_ITEMS)
|
||||||
{
|
{
|
||||||
|
DbgPrint("ERROR: RegEnumValueW failed %08x.\n", ret);
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ include_directories(
|
||||||
spec2def(stobject.dll stobject.spec)
|
spec2def(stobject.dll stobject.spec)
|
||||||
|
|
||||||
add_library(stobject SHARED
|
add_library(stobject SHARED
|
||||||
|
csystray.cpp
|
||||||
stobject.cpp
|
stobject.cpp
|
||||||
stobject.rc
|
stobject.rc
|
||||||
volume.cpp
|
volume.cpp
|
||||||
|
|
200
dll/win32/stobject/csystray.cpp
Normal file
200
dll/win32/stobject/csystray.cpp
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS system libraries
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: dll\win32\stobject\csystray.cpp
|
||||||
|
* PURPOSE: Systray shell service object implementation
|
||||||
|
* PROGRAMMERS: David Quintana <gigaherz@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "precomp.h"
|
||||||
|
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(stobject);
|
||||||
|
|
||||||
|
const GUID CLSID_SysTray = { 0x35CEC8A3, 0x2BE6, 0x11D2, { 0x87, 0x73, 0x92, 0xE2, 0x20, 0x52, 0x41, 0x53 } };
|
||||||
|
|
||||||
|
CSysTray::CSysTray() {}
|
||||||
|
CSysTray::~CSysTray() {}
|
||||||
|
|
||||||
|
HRESULT CSysTray::InitIcons()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < g_NumIcons; i++)
|
||||||
|
{
|
||||||
|
HRESULT hr = g_IconHandlers[i].pfnInit(this);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CSysTray::ShutdownIcons()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < g_NumIcons; i++)
|
||||||
|
{
|
||||||
|
HRESULT hr = g_IconHandlers[i].pfnShutdown(this);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CSysTray::UpdateIcons()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < g_NumIcons; i++)
|
||||||
|
{
|
||||||
|
HRESULT hr = g_IconHandlers[i].pfnUpdate(this);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CSysTray::ProcessIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < g_NumIcons; i++)
|
||||||
|
{
|
||||||
|
HRESULT hr = g_IconHandlers[i].pfnMessage(this, uMsg, wParam, lParam);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
if (hr != S_FALSE)
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CSysTray::NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip)
|
||||||
|
{
|
||||||
|
NOTIFYICONDATA nim;
|
||||||
|
nim.cbSize = sizeof(NOTIFYICONDATA);
|
||||||
|
nim.uFlags = NIF_ICON | NIF_STATE | NIF_TIP;
|
||||||
|
nim.hIcon = hIcon;
|
||||||
|
nim.uID = uId;
|
||||||
|
nim.uCallbackMessage = uId;
|
||||||
|
nim.dwState = 0;
|
||||||
|
nim.dwStateMask = 0;
|
||||||
|
nim.hWnd = m_hWnd;
|
||||||
|
nim.uVersion = NOTIFYICON_VERSION;
|
||||||
|
if (szTip)
|
||||||
|
StringCchCopy(nim.szTip, _countof(nim.szTip), szTip);
|
||||||
|
else
|
||||||
|
nim.szTip[0] = 0;
|
||||||
|
BOOL ret = Shell_NotifyIcon(code, &nim);
|
||||||
|
return ret ? S_OK : E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD WINAPI CSysTray::s_SysTrayThreadProc(PVOID param)
|
||||||
|
{
|
||||||
|
CSysTray * st = (CSysTray*) param;
|
||||||
|
return st->SysTrayThreadProc();
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CSysTray::SysTrayMessageLoop()
|
||||||
|
{
|
||||||
|
BOOL ret;
|
||||||
|
MSG msg;
|
||||||
|
|
||||||
|
while ((ret = GetMessage(&msg, NULL, 0, 0)) != 0)
|
||||||
|
{
|
||||||
|
if (ret < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CSysTray::SysTrayThreadProc()
|
||||||
|
{
|
||||||
|
WCHAR strFileName[MAX_PATH];
|
||||||
|
GetModuleFileNameW(g_hInstance, strFileName, MAX_PATH);
|
||||||
|
HMODULE hLib = LoadLibraryW(strFileName);
|
||||||
|
|
||||||
|
CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED);
|
||||||
|
|
||||||
|
Create(NULL);
|
||||||
|
|
||||||
|
HRESULT ret = SysTrayMessageLoop();
|
||||||
|
|
||||||
|
CoUninitialize();
|
||||||
|
|
||||||
|
FreeLibraryAndExitThread(hLib, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CSysTray::CreateSysTrayThread()
|
||||||
|
{
|
||||||
|
DbgPrint("CSysTray Init TODO: Initialize tray icon handlers.\n");
|
||||||
|
|
||||||
|
HANDLE hThread = CreateThread(NULL, 0, s_SysTrayThreadProc, this, 0, NULL);
|
||||||
|
|
||||||
|
CloseHandle(hThread);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT CSysTray::DestroySysTrayWindow()
|
||||||
|
{
|
||||||
|
DestroyWindow();
|
||||||
|
hwndSysTray = NULL;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *** IOleCommandTarget methods ***
|
||||||
|
HRESULT STDMETHODCALLTYPE CSysTray::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT STDMETHODCALLTYPE CSysTray::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
|
||||||
|
{
|
||||||
|
if (!IsEqualGUID(*pguidCmdGroup, CGID_ShellServiceObject))
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
switch (nCmdID)
|
||||||
|
{
|
||||||
|
case OLECMDID_NEW: // init
|
||||||
|
return CreateSysTrayThread();
|
||||||
|
case OLECMDID_SAVE: // shutdown
|
||||||
|
return DestroySysTrayWindow();
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CSysTray::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult, DWORD dwMsgMapID)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (hWnd != m_hWnd)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case WM_CREATE:
|
||||||
|
InitIcons();
|
||||||
|
SetTimer(1, 2000, NULL);
|
||||||
|
return TRUE;
|
||||||
|
case WM_TIMER:
|
||||||
|
UpdateIcons();
|
||||||
|
return TRUE;
|
||||||
|
case WM_DESTROY:
|
||||||
|
ShutdownIcons();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DbgPrint("SysTray message received %u (%08p %08p)\n", uMsg, wParam, lParam);
|
||||||
|
|
||||||
|
hr = ProcessIconMessage(uMsg, wParam, lParam);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (hr == S_FALSE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
66
dll/win32/stobject/csystray.h
Normal file
66
dll/win32/stobject/csystray.h
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS system libraries
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: dll\win32\stobject\stobject.cpp
|
||||||
|
* PURPOSE: Systray shell service object
|
||||||
|
* PROGRAMMERS: Robert Naumann
|
||||||
|
David Quintana <gigaherz@gmail.com>
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
extern const GUID CLSID_SysTray;
|
||||||
|
|
||||||
|
|
||||||
|
typedef CWinTraits <
|
||||||
|
WS_POPUP | WS_DLGFRAME | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
|
||||||
|
WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_PALETTEWINDOW
|
||||||
|
> CMessageWndClass;
|
||||||
|
|
||||||
|
class CSysTray :
|
||||||
|
public CComCoClass<CSysTray, &CLSID_SysTray>,
|
||||||
|
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||||
|
public CWindowImpl<CSysTray, CWindow, CMessageWndClass>,
|
||||||
|
public IOleCommandTarget
|
||||||
|
{
|
||||||
|
// TODO: keep icon handlers here
|
||||||
|
|
||||||
|
HWND hwndSysTray;
|
||||||
|
|
||||||
|
static DWORD WINAPI s_SysTrayThreadProc(PVOID param);
|
||||||
|
HRESULT SysTrayMessageLoop();
|
||||||
|
HRESULT SysTrayThreadProc();
|
||||||
|
HRESULT CreateSysTrayThread();
|
||||||
|
HRESULT DestroySysTrayWindow();
|
||||||
|
|
||||||
|
HRESULT InitIcons();
|
||||||
|
HRESULT ShutdownIcons();
|
||||||
|
HRESULT UpdateIcons();
|
||||||
|
HRESULT ProcessIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
public:
|
||||||
|
HRESULT NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip);
|
||||||
|
|
||||||
|
HWND GetHWnd() { return m_hWnd; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult, DWORD dwMsgMapID = 0);
|
||||||
|
|
||||||
|
public:
|
||||||
|
CSysTray();
|
||||||
|
virtual ~CSysTray();
|
||||||
|
|
||||||
|
// *** IOleCommandTarget methods ***
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText);
|
||||||
|
virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut);
|
||||||
|
|
||||||
|
DECLARE_WND_CLASS_EX(_T("SystemTray_Main"), CS_GLOBALCLASS, COLOR_3DFACE)
|
||||||
|
|
||||||
|
DECLARE_REGISTRY_RESOURCEID(IDR_SYSTRAY)
|
||||||
|
DECLARE_NOT_AGGREGATABLE(CSysTray)
|
||||||
|
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||||
|
|
||||||
|
BEGIN_COM_MAP(CSysTray)
|
||||||
|
COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
|
||||||
|
END_COM_MAP()
|
||||||
|
|
||||||
|
};
|
|
@ -34,68 +34,28 @@
|
||||||
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
extern const GUID CLSID_SysTray;
|
|
||||||
|
|
||||||
extern HINSTANCE g_hInstance;
|
extern HINSTANCE g_hInstance;
|
||||||
|
|
||||||
#define ID_ICON_VOLUME 0x4CB
|
#define ID_ICON_VOLUME 0x4CB
|
||||||
|
|
||||||
/* --------------- CSysTray callbacks ------------------------------ */
|
#include "csystray.h"
|
||||||
|
|
||||||
typedef CWinTraits <
|
typedef HRESULT(STDMETHODCALLTYPE * PFNSTINIT) (_In_ CSysTray * pSysTray);
|
||||||
WS_POPUP | WS_DLGFRAME | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
|
typedef HRESULT(STDMETHODCALLTYPE * PFNSTSHUTDOWN) (_In_ CSysTray * pSysTray);
|
||||||
WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR | WS_EX_PALETTEWINDOW
|
typedef HRESULT(STDMETHODCALLTYPE * PFNSTUPDATE) (_In_ CSysTray * pSysTray);
|
||||||
> CMessageWndClass;
|
typedef HRESULT(STDMETHODCALLTYPE * PFNSTMESSAGE) (_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
class CSysTray :
|
struct SysTrayIconHandlers_t
|
||||||
public CComCoClass<CSysTray, &CLSID_SysTray>,
|
|
||||||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
|
||||||
public CWindowImpl<CSysTray, CWindow, CMessageWndClass>,
|
|
||||||
public IOleCommandTarget
|
|
||||||
{
|
{
|
||||||
// TODO: keep icon handlers here
|
PFNSTINIT pfnInit;
|
||||||
|
PFNSTSHUTDOWN pfnShutdown;
|
||||||
HWND hwndSysTray;
|
PFNSTUPDATE pfnUpdate;
|
||||||
|
PFNSTMESSAGE pfnMessage;
|
||||||
static DWORD WINAPI s_SysTrayThreadProc(PVOID param);
|
|
||||||
HRESULT SysTrayMessageLoop();
|
|
||||||
HRESULT SysTrayThreadProc();
|
|
||||||
HRESULT CreateSysTrayThread();
|
|
||||||
HRESULT DestroySysTrayWindow();
|
|
||||||
|
|
||||||
HRESULT InitIcons();
|
|
||||||
HRESULT ShutdownIcons();
|
|
||||||
HRESULT UpdateIcons();
|
|
||||||
HRESULT ProcessIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
||||||
|
|
||||||
public:
|
|
||||||
HRESULT NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip);
|
|
||||||
|
|
||||||
HWND GetHWnd() { return m_hWnd; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult, DWORD dwMsgMapID = 0);
|
|
||||||
|
|
||||||
public:
|
|
||||||
CSysTray();
|
|
||||||
virtual ~CSysTray();
|
|
||||||
|
|
||||||
// *** IOleCommandTarget methods ***
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText);
|
|
||||||
virtual HRESULT STDMETHODCALLTYPE Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut);
|
|
||||||
|
|
||||||
DECLARE_WND_CLASS_EX(_T("SystemTray_Main"), CS_GLOBALCLASS, COLOR_3DFACE)
|
|
||||||
|
|
||||||
DECLARE_REGISTRY_RESOURCEID(IDR_SYSTRAY)
|
|
||||||
DECLARE_NOT_AGGREGATABLE(CSysTray)
|
|
||||||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
|
||||||
|
|
||||||
BEGIN_COM_MAP(CSysTray)
|
|
||||||
COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget)
|
|
||||||
END_COM_MAP()
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern SysTrayIconHandlers_t g_IconHandlers[];
|
||||||
|
extern const int g_NumIcons;
|
||||||
|
|
||||||
/* --------------- Icon callbacks ------------------------------ */
|
/* --------------- Icon callbacks ------------------------------ */
|
||||||
|
|
||||||
extern HRESULT STDMETHODCALLTYPE Volume_Init(_In_ CSysTray * pSysTray);
|
extern HRESULT STDMETHODCALLTYPE Volume_Init(_In_ CSysTray * pSysTray);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* PROJECT: ReactOS system libraries
|
* PROJECT: ReactOS system libraries
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
* FILE: dll\win32\stobject\stobject.cpp
|
* FILE: dll\win32\stobject\stobject.cpp
|
||||||
* PURPOSE: Systray shell service object
|
* PURPOSE: COM registration services for STobject.dll
|
||||||
* PROGRAMMERS: Robert Naumann
|
* PROGRAMMERS: Robert Naumann
|
||||||
David Quintana <gigaherz@gmail.com>
|
David Quintana <gigaherz@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
@ -14,253 +14,21 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(stobject);
|
WINE_DEFAULT_DEBUG_CHANNEL(stobject);
|
||||||
|
|
||||||
const GUID CLSID_SysTray = { 0x35CEC8A3, 0x2BE6, 0x11D2, { 0x87, 0x73, 0x92, 0xE2, 0x20, 0x52, 0x41, 0x53 } };
|
|
||||||
|
|
||||||
HINSTANCE g_hInstance;
|
|
||||||
|
|
||||||
typedef HRESULT(STDMETHODCALLTYPE * PFNSTINIT) (_In_ CSysTray * pSysTray);
|
|
||||||
typedef HRESULT(STDMETHODCALLTYPE * PFNSTSHUTDOWN) (_In_ CSysTray * pSysTray);
|
|
||||||
typedef HRESULT(STDMETHODCALLTYPE * PFNSTUPDATE) (_In_ CSysTray * pSysTray);
|
|
||||||
typedef HRESULT(STDMETHODCALLTYPE * PFNSTMESSAGE) (_In_ CSysTray * pSysTray, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
||||||
|
|
||||||
struct SysTrayIconHandlers_t
|
|
||||||
{
|
|
||||||
PFNSTINIT pfnInit;
|
|
||||||
PFNSTSHUTDOWN pfnShutdown;
|
|
||||||
PFNSTUPDATE pfnUpdate;
|
|
||||||
PFNSTMESSAGE pfnMessage;
|
|
||||||
};
|
|
||||||
|
|
||||||
SysTrayIconHandlers_t g_IconHandlers [] = {
|
|
||||||
{ Volume_Init, Volume_Shutdown, Volume_Update, Volume_Message }
|
|
||||||
};
|
|
||||||
const int g_NumIcons = _countof(g_IconHandlers);
|
|
||||||
|
|
||||||
HRESULT CSysTray::InitIcons()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < g_NumIcons; i++)
|
|
||||||
{
|
|
||||||
HRESULT hr = g_IconHandlers[i].pfnInit(this);
|
|
||||||
if (FAILED(hr))
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CSysTray::ShutdownIcons()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < g_NumIcons; i++)
|
|
||||||
{
|
|
||||||
HRESULT hr = g_IconHandlers[i].pfnShutdown(this);
|
|
||||||
if (FAILED(hr))
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CSysTray::UpdateIcons()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < g_NumIcons; i++)
|
|
||||||
{
|
|
||||||
HRESULT hr = g_IconHandlers[i].pfnUpdate(this);
|
|
||||||
if (FAILED(hr))
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CSysTray::ProcessIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < g_NumIcons; i++)
|
|
||||||
{
|
|
||||||
HRESULT hr = g_IconHandlers[i].pfnMessage(this, uMsg, wParam, lParam);
|
|
||||||
if (FAILED(hr))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
if (hr != S_FALSE)
|
|
||||||
return hr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CSysTray::NotifyIcon(INT code, UINT uId, HICON hIcon, LPCWSTR szTip)
|
|
||||||
{
|
|
||||||
NOTIFYICONDATA nim;
|
|
||||||
nim.cbSize = sizeof(NOTIFYICONDATA);
|
|
||||||
nim.uFlags = NIF_ICON | NIF_STATE | NIF_TIP;
|
|
||||||
nim.hIcon = hIcon;
|
|
||||||
nim.uID = uId;
|
|
||||||
nim.uCallbackMessage = uId;
|
|
||||||
nim.dwState = 0;
|
|
||||||
nim.dwStateMask = 0;
|
|
||||||
nim.hWnd = m_hWnd;
|
|
||||||
nim.uVersion = NOTIFYICON_VERSION;
|
|
||||||
if (szTip)
|
|
||||||
StringCchCopy(nim.szTip, _countof(nim.szTip), szTip);
|
|
||||||
else
|
|
||||||
nim.szTip[0] = 0;
|
|
||||||
BOOL ret = Shell_NotifyIcon(code, &nim);
|
|
||||||
return ret ? S_OK : E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD WINAPI CSysTray::s_SysTrayThreadProc(PVOID param)
|
|
||||||
{
|
|
||||||
CSysTray * st = (CSysTray*) param;
|
|
||||||
return st->SysTrayThreadProc();
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CSysTray::SysTrayMessageLoop()
|
|
||||||
{
|
|
||||||
BOOL ret;
|
|
||||||
MSG msg;
|
|
||||||
|
|
||||||
while ((ret = GetMessage(&msg, NULL, 0, 0)) != 0)
|
|
||||||
{
|
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
TranslateMessage(&msg);
|
|
||||||
DispatchMessage(&msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CSysTray::SysTrayThreadProc()
|
|
||||||
{
|
|
||||||
WCHAR strFileName[MAX_PATH];
|
|
||||||
GetModuleFileNameW(g_hInstance, strFileName, MAX_PATH);
|
|
||||||
HMODULE hLib = LoadLibraryW(strFileName);
|
|
||||||
|
|
||||||
CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED);
|
|
||||||
|
|
||||||
Create(NULL);
|
|
||||||
|
|
||||||
HRESULT ret = SysTrayMessageLoop();
|
|
||||||
|
|
||||||
CoUninitialize();
|
|
||||||
|
|
||||||
FreeLibraryAndExitThread(hLib, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CSysTray::CreateSysTrayThread()
|
|
||||||
{
|
|
||||||
DbgPrint("CSysTray Init TODO: Initialize tray icon handlers.\n");
|
|
||||||
|
|
||||||
HANDLE hThread = CreateThread(NULL, 0, s_SysTrayThreadProc, this, 0, NULL);
|
|
||||||
|
|
||||||
CloseHandle(hThread);
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT CSysTray::DestroySysTrayWindow()
|
|
||||||
{
|
|
||||||
DestroyWindow();
|
|
||||||
hwndSysTray = NULL;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
CSysTray::CSysTray() {}
|
|
||||||
CSysTray::~CSysTray() {}
|
|
||||||
|
|
||||||
// *** IOleCommandTarget methods ***
|
|
||||||
HRESULT STDMETHODCALLTYPE CSysTray::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE CSysTray::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
|
|
||||||
{
|
|
||||||
if (!IsEqualGUID(*pguidCmdGroup, CGID_ShellServiceObject))
|
|
||||||
return E_FAIL;
|
|
||||||
|
|
||||||
switch (nCmdID)
|
|
||||||
{
|
|
||||||
case OLECMDID_NEW: // init
|
|
||||||
return CreateSysTrayThread();
|
|
||||||
case OLECMDID_SAVE: // shutdown
|
|
||||||
return DestroySysTrayWindow();
|
|
||||||
}
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL CSysTray::ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult, DWORD dwMsgMapID)
|
|
||||||
{
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
if (hWnd != m_hWnd)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
switch (uMsg)
|
|
||||||
{
|
|
||||||
case WM_CREATE:
|
|
||||||
InitIcons();
|
|
||||||
SetTimer(1, 2000, NULL);
|
|
||||||
return TRUE;
|
|
||||||
case WM_TIMER:
|
|
||||||
UpdateIcons();
|
|
||||||
return TRUE;
|
|
||||||
case WM_DESTROY:
|
|
||||||
ShutdownIcons();
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
DbgPrint("SysTray message received %u (%08p %08p)\n", uMsg, wParam, lParam);
|
|
||||||
|
|
||||||
hr = ProcessIconMessage(uMsg, wParam, lParam);
|
|
||||||
if (FAILED(hr))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (hr == S_FALSE)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_OBJECT_MAP(ObjectMap)
|
BEGIN_OBJECT_MAP(ObjectMap)
|
||||||
OBJECT_ENTRY(CLSID_SysTray, CSysTray)
|
OBJECT_ENTRY(CLSID_SysTray, CSysTray)
|
||||||
END_OBJECT_MAP()
|
END_OBJECT_MAP()
|
||||||
|
|
||||||
class CShellTrayModule : public CComModule
|
class CShellTrayModule : public CComModule
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
};
|
};
|
||||||
|
|
||||||
CShellTrayModule gModule;
|
HINSTANCE g_hInstance;
|
||||||
|
CShellTrayModule g_Module;
|
||||||
|
SysTrayIconHandlers_t g_IconHandlers [] = {
|
||||||
HRESULT RegisterShellServiceObject(REFGUID guidClass, LPCWSTR lpName, BOOL bRegister)
|
{ Volume_Init, Volume_Shutdown, Volume_Update, Volume_Message }
|
||||||
{
|
};
|
||||||
const LPCWSTR strRegistryLocation = L"Software\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad";
|
const int g_NumIcons = _countof(g_IconHandlers);
|
||||||
|
|
||||||
OLECHAR strGuid[128]; // shouldn't need so much!
|
|
||||||
LSTATUS ret = 0;
|
|
||||||
HKEY hKey = 0;
|
|
||||||
if (StringFromGUID2(guidClass, strGuid, 128))
|
|
||||||
{
|
|
||||||
if (!RegOpenKeyExW(HKEY_LOCAL_MACHINE, strRegistryLocation, 0, KEY_WRITE, &hKey))
|
|
||||||
{
|
|
||||||
if (bRegister)
|
|
||||||
{
|
|
||||||
LONG cbGuid = (lstrlenW(strGuid) + 1) * 2;
|
|
||||||
ret = RegSetValueExW(hKey, lpName, 0, REG_SZ, (const BYTE *) strGuid, cbGuid);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret = RegDeleteValueW(hKey, lpName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hKey)
|
|
||||||
RegCloseKey(hKey);
|
|
||||||
return /*HRESULT_FROM_NT*/(ret); // regsvr32 considers anything != S_OK to be an error
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void *operator new (size_t, void *buf)
|
void *operator new (size_t, void *buf)
|
||||||
{
|
{
|
||||||
|
@ -273,55 +41,123 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
|
||||||
{
|
{
|
||||||
if (fdwReason == DLL_PROCESS_ATTACH)
|
if (fdwReason == DLL_PROCESS_ATTACH)
|
||||||
{
|
{
|
||||||
|
g_hInstance = hinstDLL;
|
||||||
|
DisableThreadLibraryCalls(g_hInstance);
|
||||||
|
|
||||||
/* HACK - the global constructors don't run, so I placement new them here */
|
/* HACK - the global constructors don't run, so I placement new them here */
|
||||||
new (&gModule) CShellTrayModule;
|
new (&g_Module) CShellTrayModule;
|
||||||
new (&_AtlWinModule) CAtlWinModule;
|
new (&_AtlWinModule) CAtlWinModule;
|
||||||
new (&_AtlBaseModule) CAtlBaseModule;
|
new (&_AtlBaseModule) CAtlBaseModule;
|
||||||
new (&_AtlComModule) CAtlComModule;
|
new (&_AtlComModule) CAtlComModule;
|
||||||
|
|
||||||
g_hInstance = hinstDLL;
|
g_Module.Init(ObjectMap, g_hInstance, NULL);
|
||||||
DisableThreadLibraryCalls(g_hInstance);
|
|
||||||
|
|
||||||
gModule.Init(ObjectMap, g_hInstance, NULL);
|
|
||||||
}
|
}
|
||||||
else if (fdwReason == DLL_PROCESS_DETACH)
|
else if (fdwReason == DLL_PROCESS_DETACH)
|
||||||
{
|
{
|
||||||
g_hInstance = NULL;
|
g_hInstance = NULL;
|
||||||
gModule.Term();
|
g_Module.Term();
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
HRESULT
|
||||||
|
RegisterShellServiceObject(REFGUID guidClass, LPCWSTR lpName, BOOL bRegister)
|
||||||
|
{
|
||||||
|
const LPCWSTR strRegistryLocation = L"Software\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad";
|
||||||
|
|
||||||
|
HRESULT hr = E_FAIL;
|
||||||
|
|
||||||
|
OLECHAR strGuid[128];
|
||||||
|
|
||||||
|
HKEY hKey = 0;
|
||||||
|
|
||||||
|
if (!StringFromGUID2(guidClass, strGuid, _countof(strGuid)))
|
||||||
|
{
|
||||||
|
DbgPrint("StringFromGUID2 failed\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, strRegistryLocation, 0, KEY_WRITE, &hKey))
|
||||||
|
{
|
||||||
|
DbgPrint("RegOpenKeyExW failed\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bRegister)
|
||||||
|
{
|
||||||
|
LONG cbGuid = (lstrlenW(strGuid) + 1) * 2;
|
||||||
|
if (RegSetValueExW(hKey, lpName, 0, REG_SZ, (const BYTE *) strGuid, cbGuid))
|
||||||
|
{
|
||||||
|
DbgPrint("RegSetValueExW failed\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (RegDeleteValueW(hKey, lpName))
|
||||||
|
{
|
||||||
|
DbgPrint("RegDeleteValueW failed\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = S_OK;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (hKey)
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDAPI
|
||||||
|
DllRegisterServer(void)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = g_Module.DllRegisterServer(FALSE);
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
hr = RegisterShellServiceObject(CLSID_SysTray, L"SysTray", TRUE);
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDAPI
|
||||||
|
DllUnregisterServer(void)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = RegisterShellServiceObject(CLSID_SysTray, L"SysTray", FALSE);
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
hr = g_Module.DllUnregisterServer(FALSE);
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDAPI
|
||||||
|
DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = g_Module.DllGetClassObject(rclsid, riid, ppv);
|
||||||
|
if (FAILED_UNEXPECTEDLY(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
WINAPI
|
WINAPI
|
||||||
DllCanUnloadNow(void)
|
DllCanUnloadNow(void)
|
||||||
{
|
{
|
||||||
return gModule.DllCanUnloadNow();
|
return g_Module.DllCanUnloadNow();
|
||||||
}
|
|
||||||
|
|
||||||
STDAPI
|
|
||||||
DllRegisterServer(void)
|
|
||||||
{
|
|
||||||
HRESULT hr = gModule.DllRegisterServer(FALSE);
|
|
||||||
if (FAILED(hr))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
return RegisterShellServiceObject(CLSID_SysTray, L"SysTray", TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
STDAPI
|
|
||||||
DllUnregisterServer(void)
|
|
||||||
{
|
|
||||||
RegisterShellServiceObject(CLSID_SysTray, L"SysTray", FALSE);
|
|
||||||
|
|
||||||
return gModule.DllUnregisterServer(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
STDAPI
|
|
||||||
DllGetClassObject(
|
|
||||||
REFCLSID rclsid,
|
|
||||||
REFIID riid,
|
|
||||||
LPVOID *ppv)
|
|
||||||
{
|
|
||||||
return gModule.DllGetClassObject(rclsid, riid, ppv);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,8 @@
|
||||||
* PROJECT: ReactOS system libraries
|
* PROJECT: ReactOS system libraries
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
* FILE: dll\win32\stobject\volume.cpp
|
* FILE: dll\win32\stobject\volume.cpp
|
||||||
* PURPOSE: Systray shell service object
|
* PURPOSE: Volume notification icon handler
|
||||||
* PROGRAMMERS: Robert Naumann
|
* PROGRAMMERS: David Quintana <gigaherz@gmail.com>
|
||||||
David Quintana <gigaherz@gmail.com>
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precomp.h"
|
#include "precomp.h"
|
||||||
|
@ -12,6 +11,8 @@
|
||||||
#include <mmsystem.h>
|
#include <mmsystem.h>
|
||||||
#include <mmddk.h>
|
#include <mmddk.h>
|
||||||
|
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(stobject);
|
||||||
|
|
||||||
HICON g_hIconVolume;
|
HICON g_hIconVolume;
|
||||||
HICON g_hIconMute;
|
HICON g_hIconMute;
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@ static HRESULT __stdcall Volume_FindMixerControl(CSysTray * pSysTray)
|
||||||
|
|
||||||
DbgPrint("Volume_FindDefaultMixerID\n");
|
DbgPrint("Volume_FindDefaultMixerID\n");
|
||||||
|
|
||||||
result = waveOutMessage((HWAVEOUT) WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD) &waveOutId, (DWORD) ¶m2);
|
result = waveOutMessage((HWAVEOUT) WAVE_MAPPER, DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR) &waveOutId, (DWORD_PTR) ¶m2);
|
||||||
if (result)
|
if (result)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue