diff options
author | Alex Marsev <alex.marsev@gmail.com> | 2015-08-04 19:01:15 +0300 |
---|---|---|
committer | Alex Marsev <alex.marsev@gmail.com> | 2015-08-05 12:58:01 +0300 |
commit | 34bd5cb1bba5fa77743bda5499f8a791b345c6e5 (patch) | |
tree | 7c4c0d073a016e5903bf7445e5c160bd9cd12bb5 | |
parent | 4aa2f2fb2ea98b3197c621a965cf91bd9b93cae0 (diff) |
Fix status page for players not based on MPC
ISpecifyPropertyPages2 worked fine, ISpecifyPropertyPages was broken.
-rw-r--r-- | dll/src/sanear-dll/Entry.cpp | 19 | ||||
-rw-r--r-- | dll/src/sanear-dll/OuterFilter.cpp | 3 | ||||
-rw-r--r-- | src/MyFilter.cpp | 35 | ||||
-rw-r--r-- | src/MyFilter.h | 4 | ||||
-rw-r--r-- | src/MyPropertyPage.cpp | 105 | ||||
-rw-r--r-- | src/MyPropertyPage.h | 16 |
6 files changed, 137 insertions, 45 deletions
diff --git a/dll/src/sanear-dll/Entry.cpp b/dll/src/sanear-dll/Entry.cpp index 9cabd03..9167b20 100644 --- a/dll/src/sanear-dll/Entry.cpp +++ b/dll/src/sanear-dll/Entry.cpp @@ -1,14 +1,17 @@ #include "pch.h"
#include "OuterFilter.h"
+#include "../../../src/MyPropertyPage.h"
namespace
{
// {DF557071-C9FD-433A-9627-81E0D3640ED9}
const GUID filterGuid = {0xdf557071, 0xc9fd, 0x433a, {0x96, 0x27, 0x81, 0xe0, 0xd3, 0x64, 0xe, 0xd9}};
-
const WCHAR filterName[] = L"Sanear Audio Renderer";
+ const GUID statusPageGuid = __uuidof(SaneAudioRenderer::MyPropertyPage);
+ const WCHAR statusPageName[] = L"Sanear Status Page";
+
const AMOVIESETUP_MEDIATYPE pinTypes[] = {
{&MEDIATYPE_Audio, &CLSID_NULL},
};
@@ -23,9 +26,11 @@ namespace }
CUnknown* WINAPI CreateFilterInstance(LPUNKNOWN, HRESULT*);
+CUnknown* WINAPI CreateStatusPageInstance(LPUNKNOWN, HRESULT*);
CFactoryTemplate g_Templates[] = {
{filterName, &filterGuid, CreateFilterInstance},
+ {statusPageName, &statusPageGuid, CreateStatusPageInstance},
};
int g_cTemplates = _countof(g_Templates);
@@ -106,6 +111,18 @@ CUnknown* WINAPI CreateFilterInstance(IUnknown* pUnknown, HRESULT* pResult) return pFilter;
}
+CUnknown* WINAPI CreateStatusPageInstance(IUnknown* pUnknown, HRESULT* pResult)
+{
+ CheckPointer(pResult, nullptr);
+
+ auto pFilter = new(std::nothrow) SaneAudioRenderer::MyPropertyPage();
+
+ if (!pFilter)
+ *pResult = E_OUTOFMEMORY;
+
+ return pFilter;
+}
+
STDAPI DllRegisterServer()
{
if (!IsWindowsVistaOrGreater())
diff --git a/dll/src/sanear-dll/OuterFilter.cpp b/dll/src/sanear-dll/OuterFilter.cpp index 084e869..fdd6b73 100644 --- a/dll/src/sanear-dll/OuterFilter.cpp +++ b/dll/src/sanear-dll/OuterFilter.cpp @@ -56,6 +56,9 @@ namespace SaneAudioRenderer if (riid == IID_IUnknown)
return CUnknown::NonDelegatingQueryInterface(riid, ppv);
+ if (riid == IID_ISpecifyPropertyPages)
+ return m_innerFilter->QueryInterface(__uuidof(ISpecifyPropertyPages2), ppv);
+
return m_innerFilter->QueryInterface(riid, ppv);
}
diff --git a/src/MyFilter.cpp b/src/MyFilter.cpp index 557545b..ca6ab99 100644 --- a/src/MyFilter.cpp +++ b/src/MyFilter.cpp @@ -7,7 +7,6 @@ #include "MyClock.h"
#include "MyTestClock.h"
#include "MyPin.h"
-#include "MyPropertyPage.h"
namespace SaneAudioRenderer
{
@@ -69,6 +68,9 @@ namespace SaneAudioRenderer if (riid == __uuidof(ISpecifyPropertyPages2))
return GetInterface(static_cast<ISpecifyPropertyPages2*>(this), ppv);
+ if (riid == __uuidof(IStatusPageData))
+ return GetInterface(static_cast<IStatusPageData*>(this), ppv);
+
return CBaseFilter::NonDelegatingQueryInterface(riid, ppv);
}
@@ -151,6 +153,21 @@ namespace SaneAudioRenderer MyPropertyPage* pPage;
+ pPage = new(std::nothrow) MyPropertyPage();
+
+ CheckPointer(pPage, E_OUTOFMEMORY);
+
+ pPage->AddRef();
+
+ HRESULT result = pPage->QueryInterface(IID_PPV_ARGS(ppPage));
+
+ pPage->Release();
+
+ return result;
+ }
+
+ STDMETHODIMP MyFilter::GetPageData(std::vector<char>& data)
+ {
try
{
CAutoLock rendererLock(m_renderer.get());
@@ -158,23 +175,17 @@ namespace SaneAudioRenderer auto inputFormat = m_renderer->GetInputFormat();
auto audioDevice = m_renderer->GetAudioDevice();
- pPage = new MyPropertyPage(inputFormat, audioDevice,
- m_renderer->GetActiveProcessors(),
- m_renderer->OnExternalClock(),
- m_renderer->IsLive());
+ data = MyPropertyPage::CreateDialogData(inputFormat, audioDevice,
+ m_renderer->GetActiveProcessors(),
+ m_renderer->OnExternalClock(),
+ m_renderer->IsLive());
}
catch (std::bad_alloc&)
{
return E_OUTOFMEMORY;
}
- pPage->AddRef();
-
- HRESULT result = pPage->QueryInterface(IID_PPV_ARGS(ppPage));
-
- pPage->Release();
-
- return result;
+ return S_OK;
}
template <FILTER_STATE NewState, typename PinFunction>
diff --git a/src/MyFilter.h b/src/MyFilter.h index a4a92aa..f377ded 100644 --- a/src/MyFilter.h +++ b/src/MyFilter.h @@ -1,6 +1,7 @@ #pragma once
#include "Interfaces.h"
+#include "MyPropertyPage.h"
namespace SaneAudioRenderer
{
@@ -13,6 +14,7 @@ namespace SaneAudioRenderer : public CCritSec
, public CBaseFilter
, public ISpecifyPropertyPages2
+ , public IStatusPageData
{
public:
@@ -40,6 +42,8 @@ namespace SaneAudioRenderer STDMETHODIMP GetPages(CAUUID* pPages) override;
STDMETHODIMP CreatePage(const GUID& guid, IPropertyPage** ppPage) override;
+ STDMETHODIMP GetPageData(std::vector<char>& data) override;
+
private:
template <FILTER_STATE NewState, typename PinFunction>
diff --git a/src/MyPropertyPage.cpp b/src/MyPropertyPage.cpp index 129019b..6574c64 100644 --- a/src/MyPropertyPage.cpp +++ b/src/MyPropertyPage.cpp @@ -27,7 +27,7 @@ namespace SaneAudioRenderer Write(out, (void*)str.c_str(), sizeof(wchar_t) * (str.length() + 1));
}
- void WriteDialogHeader(std::vector<char>& out, const std::wstring& font, WORD fontSize)
+ void WriteDialogHeader(std::vector<char>& out, const std::wstring& font, WORD fontSize, short w, short h)
{
assert(out.empty());
@@ -36,8 +36,8 @@ namespace SaneAudioRenderer Write<WORD>(out, 0);
Write<short>(out, 0);
Write<short>(out, 0);
- Write<short>(out, 0);
- Write<short>(out, 0);
+ Write<short>(out, w);
+ Write<short>(out, h);
Write<WORD>(out, 0);
Write<WORD>(out, 0);
WriteString(out, L"");
@@ -123,9 +123,8 @@ namespace SaneAudioRenderer }
}
- MyPropertyPage::MyPropertyPage(SharedWaveFormat inputFormat, const AudioDevice* pDevice,
- std::vector<std::wstring> processors, bool externalClock, bool live)
- : CUnknown(L"SaneAudioRenderer::MyPropertyPage", nullptr)
+ std::vector<char> MyPropertyPage::CreateDialogData(SharedWaveFormat inputFormat, const AudioDevice* pDevice,
+ std::vector<std::wstring> processors, bool externalClock, bool live)
{
std::wstring adapterField = (pDevice && pDevice->GetAdapterName()) ? *pDevice->GetAdapterName() : L"-";
@@ -169,28 +168,38 @@ namespace SaneAudioRenderer if (processorsField.empty())
processorsField = L"-";
- WriteDialogHeader(m_dialogData, L"MS Shell Dlg", 8);
- WriteDialogItem(m_dialogData, BS_GROUPBOX, 0x0080FFFF, 5, 5, 210, 150, L"Renderer Status");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 20, 60, 8, L"Adapter:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 20, 130, 8, adapterField);
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 32, 60, 8, L"Endpoint:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 32, 130, 8, endpointField);
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 44, 60, 8, L"Exclusive:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 44, 130, 8, exclusiveField);
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 56, 60, 8, L"Buffer:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 56, 130, 8, bufferField);
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 68, 60, 8, L"Bitstreaming:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 68, 130, 8, bitstreamingField);
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 80, 60, 8, L"Slaving:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 80, 130, 8, slavingField);
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 92, 60, 8, L"Format:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 92, 130, 8, formatField);
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 104, 60, 8, L"Channels:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 104, 130, 8, channelsField);
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 116, 60, 8, L"Rate:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 116, 130, 8, rateField);
- WriteDialogItem(m_dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 128, 60, 8, L"Processors:");
- WriteDialogItem(m_dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 128, 130, 24, processorsField);
+ std::vector<char> dialogData;
+
+ WriteDialogHeader(dialogData, L"MS Shell Dlg", 8, 220, 160);
+ WriteDialogItem(dialogData, BS_GROUPBOX, 0x0080FFFF, 5, 5, 210, 150, L"Renderer Status");
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 20, 60, 8, L"Adapter:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 20, 130, 8, adapterField);
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 32, 60, 8, L"Endpoint:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 32, 130, 8, endpointField);
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 44, 60, 8, L"Exclusive:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 44, 130, 8, exclusiveField);
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 56, 60, 8, L"Buffer:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 56, 130, 8, bufferField);
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 68, 60, 8, L"Bitstreaming:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 68, 130, 8, bitstreamingField);
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 80, 60, 8, L"Slaving:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 80, 130, 8, slavingField);
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 92, 60, 8, L"Format:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 92, 130, 8, formatField);
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 104, 60, 8, L"Channels:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 104, 130, 8, channelsField);
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 116, 60, 8, L"Rate:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 116, 130, 8, rateField);
+ WriteDialogItem(dialogData, BS_TEXT | SS_RIGHT, 0x0082FFFF, 10, 128, 60, 8, L"Processors:");
+ WriteDialogItem(dialogData, BS_TEXT | SS_LEFT, 0x0082FFFF, 73, 128, 130, 24, processorsField);
+
+ return dialogData;
+ }
+
+ MyPropertyPage::MyPropertyPage()
+ : CUnknown(L"SaneAudioRenderer::MyPropertyPage", nullptr)
+ {
+ m_dialogData = CreateDialogData(nullptr, nullptr, {}, false, false);
}
STDMETHODIMP MyPropertyPage::NonDelegatingQueryInterface(REFIID riid, void** ppv)
@@ -215,9 +224,17 @@ namespace SaneAudioRenderer {
CheckPointer(pRect, E_POINTER);
+ if (m_hWindow)
+ return E_UNEXPECTED;
+
m_hWindow = CreateDialogIndirect(GetModuleHandle(nullptr), (LPCDLGTEMPLATE)m_dialogData.data(), hParent, nullptr);
- return (m_hWindow != NULL) ? S_OK : E_UNEXPECTED;
+ if (!m_hWindow)
+ return E_OUTOFMEMORY;
+
+ Move(pRect);
+
+ return S_OK;
}
STDMETHODIMP MyPropertyPage::Deactivate()
@@ -243,6 +260,36 @@ namespace SaneAudioRenderer pPageInfo->pszHelpFile = nullptr;
pPageInfo->dwHelpContext = 0;
+ // This is how GetDialogSize() from DirectShow Base Classes does it.
+ HWND hWindow = CreateDialogIndirect(GetModuleHandle(nullptr), (LPCDLGTEMPLATE)m_dialogData.data(), GetDesktopWindow(), nullptr);
+ if (hWindow)
+ {
+ RECT rect;
+ if (GetWindowRect(hWindow, &rect))
+ {
+ pPageInfo->size.cx = rect.right - rect.left;
+ pPageInfo->size.cy = rect.bottom - rect.top;
+ }
+
+ DestroyWindow(hWindow);
+ }
+
+ return S_OK;
+ }
+
+ STDMETHODIMP MyPropertyPage::SetObjects(ULONG nObjects, IUnknown** ppUnk)
+ {
+ if (nObjects != 1)
+ return E_UNEXPECTED;
+
+ CheckPointer(ppUnk, E_POINTER);
+ CheckPointer(ppUnk[0], E_POINTER);
+
+ IStatusPageDataPtr data;
+ ReturnIfFailed(ppUnk[0]->QueryInterface(IID_PPV_ARGS(&data)));
+
+ ReturnIfFailed(data->GetPageData(m_dialogData));
+
return S_OK;
}
diff --git a/src/MyPropertyPage.h b/src/MyPropertyPage.h index 7b39414..53ef9c6 100644 --- a/src/MyPropertyPage.h +++ b/src/MyPropertyPage.h @@ -4,6 +4,14 @@ namespace SaneAudioRenderer {
class AudioDevice;
+ // NOTE: This is internal interface and shouldn't be used outside of Sanear.
+ struct __declspec(uuid("361657BC-CC1E-420A-BE7B-21C34E3D9F76"))
+ IStatusPageData : IUnknown
+ {
+ STDMETHOD(GetPageData)(std::vector<char>& data) = 0;
+ };
+ _COM_SMARTPTR_TYPEDEF(IStatusPageData, __uuidof(IStatusPageData));
+
class _declspec(uuid("7EEEDEC8-8B8E-4220-AF12-08BC0CE844F0"))
MyPropertyPage final
: public CUnknown
@@ -11,8 +19,10 @@ namespace SaneAudioRenderer {
public:
- MyPropertyPage(SharedWaveFormat inputFormat, const AudioDevice* device,
- std::vector<std::wstring> processors, bool externalClock, bool live);
+ static std::vector<char> CreateDialogData(SharedWaveFormat inputFormat, const AudioDevice* device,
+ std::vector<std::wstring> processors, bool externalClock, bool live);
+
+ MyPropertyPage();
MyPropertyPage(const MyPropertyPage&) = delete;
MyPropertyPage& operator=(const MyPropertyPage&) = delete;
@@ -24,7 +34,7 @@ namespace SaneAudioRenderer STDMETHODIMP Activate(HWND hParent, LPCRECT pRect, BOOL bModal) override;
STDMETHODIMP Deactivate() override;
STDMETHODIMP GetPageInfo(PROPPAGEINFO* pPageInfo) override;
- STDMETHODIMP SetObjects(ULONG, IUnknown**) override { return S_OK; }
+ STDMETHODIMP SetObjects(ULONG nObjects, IUnknown** ppUnk) override;
STDMETHODIMP Show(UINT cmdShow) override;
STDMETHODIMP Move(LPCRECT pRect) override;
STDMETHODIMP IsPageDirty() override { return S_FALSE; }
|