Skip to content

Instantly share code, notes, and snippets.

@WamWooWam
Last active November 26, 2019 08:41
Show Gist options
  • Save WamWooWam/50a402e41a9f7c5c9039f0d6a5c40766 to your computer and use it in GitHub Desktop.
Save WamWooWam/50a402e41a9f7c5c9039f0d6a5c40766 to your computer and use it in GitHub Desktop.
// DangerBin.cpp : Plays audio at an increasing volume the nearer the pointer is to the Recycle Bin.
// Compile with anything targeting the Windows 8.1 SDK or later
#include <iostream>
#include <wrl.h>
#include <shlobj.h>
#include <exdisp.h>
#include <comutil.h>
#include <roapi.h>
#include <shlwapi.h>
#include <mfapi.h>
#include <mfidl.h>
#include <tchar.h>
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "oleaut32.lib")
#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "mf.lib")
#pragma comment(lib, "mfplat.lib")
#pragma comment(lib, "mfuuid.lib")
// i hate COM
#define COM_CALL(x) if (FAILED(hr = x)) return hr
using namespace Microsoft::WRL;
HRESULT FindDesktopFolderView(REFIID riid, void** ppv)
{
ComPtr<IShellWindows> spShellWindows;
ComPtr<IDispatch> spdisp;
ComPtr<IShellBrowser> spBrowser;
ComPtr<IServiceProvider> spServiceProvider;
ComPtr<IShellView> spView;
long lhwnd;
HRESULT hr = S_OK;
COM_CALL(CoCreateInstance(CLSID_ShellWindows, nullptr, CLSCTX_ALL, IID_IShellWindows, &spShellWindows));
COM_CALL(spShellWindows->FindWindowSW(&_variant_t(CSIDL_DESKTOP), &_variant_t(), SWC_DESKTOP, &lhwnd, SWFO_NEEDDISPATCH, &spdisp));
COM_CALL(spdisp.As(&spServiceProvider));
COM_CALL(spServiceProvider->QueryService(SID_STopLevelBrowser, spBrowser.GetAddressOf()));
COM_CALL(spBrowser->QueryActiveShellView(&spView));
COM_CALL(spView->QueryInterface(riid, ppv));
return S_OK;
}
HRESULT GetRecycleBinItem(ComPtr<IFolderView>& spView, ITEMID_CHILD*& item, TCHAR*& name)
{
HRESULT hr = S_OK;
ComPtr<IShellFolder> spFolder;
if (FAILED(hr = spView->GetFolder(IID_PPV_ARGS(&spFolder))))
return hr;
ComPtr<IEnumIDList> spEnum;
if (FAILED(hr = spView->Items(SVGIO_ALLVIEW, IID_PPV_ARGS(&spEnum))))
return hr;
STRRET str;
while (SUCCEEDED(spEnum->Next(1, &item, nullptr)))
{
if (FAILED(hr = spFolder->GetDisplayNameOf(item, SHGDN_FORPARSING, &str)))
continue;
if (FAILED(hr = StrRetToStr(&str, item, &name)))
continue;
// recycle bin GUID magic
if (_tcscmp(name, TEXT("::{645FF040-5081-101B-9F08-00AA002F954E}")) == 0) {
break;
}
CoTaskMemFree(name);
}
return hr;
}
int main()
{
HRESULT hr;
COM_CALL(CoInitializeEx(nullptr, COINIT_MULTITHREADED));
COM_CALL(MFStartup(MF_VERSION, MFSTARTUP_LITE));
ComPtr<IFolderView> spView;
COM_CALL(FindDesktopFolderView(IID_IFolderView, &spView));
POINT itemSize;
memset(&itemSize, 0, sizeof itemSize);
COM_CALL(spView->GetSpacing(&itemSize));
TCHAR* name = nullptr;
ITEMID_CHILD* item = (ITEMID_CHILD*)CoTaskMemAlloc(sizeof(ITEMID_CHILD));
COM_CALL(GetRecycleBinItem(spView, item, name));
if (name == nullptr)
return E_FAIL; // didn't find recycle bin :(
POINT topLeft;
COM_CALL(spView->GetItemPosition(item, &topLeft));
POINT bottomRight;
bottomRight.x = topLeft.x + itemSize.x;
bottomRight.y = topLeft.y + itemSize.y;
RECT binRect;
binRect.top = topLeft.y;
binRect.left = topLeft.x;
binRect.bottom = bottomRight.y;
binRect.right = bottomRight.x;
DWORD sourceCount;
MF_OBJECT_TYPE objectType = MF_OBJECT_TYPE::MF_OBJECT_INVALID;
ComPtr<IMFMediaSession> mediaSession;
ComPtr<IMFSourceResolver> sourceResolver;
ComPtr<IMFMediaSource> mediaSource;
ComPtr<IMFPresentationDescriptor> presentationDiscriptor;
ComPtr<IMFTopology> mediaTopology;
ComPtr<IMFTopologyNode> sourceNode;
ComPtr<IMFTopologyNode> destNode;
ComPtr<IMFActivate> sinkActivate;
ComPtr<IMFMediaSink> mediaSink;
COM_CALL(MFCreateMediaSession(NULL, &mediaSession));
COM_CALL(MFCreateSourceResolver(&sourceResolver));
COM_CALL(sourceResolver->CreateObjectFromURL(L"dangerzone.mp3", MF_RESOLUTION_MEDIASOURCE, NULL, &objectType, &mediaSource));
COM_CALL(mediaSource->CreatePresentationDescriptor(&presentationDiscriptor));
COM_CALL(MFCreateTopology(&mediaTopology));
COM_CALL(presentationDiscriptor->GetStreamDescriptorCount(&sourceCount));
for (DWORD c = 0; c < sourceCount; c++) {
ComPtr<IMFStreamDescriptor> streamDescriptor;
BOOL selected = 0;
COM_CALL(presentationDiscriptor->GetStreamDescriptorByIndex(c, &selected, &streamDescriptor));
if (selected) {
ComPtr<IMFMediaTypeHandler> handler;
COM_CALL(streamDescriptor->GetMediaTypeHandler(&handler));
GUID majorType;
COM_CALL(handler->GetMajorType(&majorType));
if (majorType == MFMediaType_Audio) {
COM_CALL(MFCreateAudioRendererActivate(&sinkActivate));
COM_CALL(MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &sourceNode));
COM_CALL(sourceNode->SetUnknown(MF_TOPONODE_SOURCE, mediaSource.Get()));
COM_CALL(sourceNode->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, presentationDiscriptor.Get()));
COM_CALL(sourceNode->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, streamDescriptor.Get()));
COM_CALL(mediaTopology->AddNode(sourceNode.Get()));
sourceNode->AddRef();
COM_CALL(MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &destNode));
COM_CALL(destNode->SetObject(sinkActivate.Get()));
COM_CALL(destNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, TRUE));
COM_CALL(mediaTopology->AddNode(destNode.Get()));
destNode->AddRef();
COM_CALL(sourceNode->ConnectOutput(0, destNode.Get(), 0));
}
else {
presentationDiscriptor->DeselectStream(c);
}
}
}
ComPtr<IMFMediaEvent> mediaEvent;
COM_CALL(mediaSession->SetTopology(NULL, mediaTopology.Get()));
COM_CALL(mediaSession->GetEvent(NULL, &mediaEvent));
COM_CALL(sinkActivate->ActivateObject(IID_PPV_ARGS(&mediaSink)));
ComPtr<IMFSimpleAudioVolume> audioVolume;
COM_CALL(MFGetService(mediaSink.Get(), MR_POLICY_VOLUME_SERVICE, IID_PPV_ARGS(&audioVolume)));
PROPVARIANT var;
PropVariantInit(&var);
POINT mouse;
bool isPlaying = false;
float volume = 0.0f;
HDC dc = GetDC(GetDesktopWindow());
while (true)
{
GetCursorPos(&mouse);
float dx = fmaxf(binRect.left - mouse.x, fmaxf(0, mouse.x - binRect.right));
float dy = fmaxf(binRect.top - mouse.y, fmaxf(0, mouse.y - binRect.bottom));
float dist = sqrtf((dx * dx) + (dy * dy));
bool intersect = (mouse.x > binRect.left&& mouse.x < binRect.right) && (mouse.y > binRect.top&& mouse.y < binRect.bottom);
if (dist < 800 && !isPlaying) {
mediaSession->Start(&GUID_NULL, &var);
isPlaying = true;
}
if (dist > 1200 && isPlaying) {
mediaSession->Stop();
isPlaying = false;
}
float nrm = max(0.0f, min(1.0f, 1 - (dist / 1200)));
volume = intersect ? 1.0f : 1.0f - sqrt(1.0f - nrm * nrm);
if (volume >= 0) {
audioVolume->SetMasterVolume(volume);
}
std::cout << isPlaying << " " << volume << "\n";
Sleep(1);
}
mediaSession->Shutdown();
CoTaskMemFree(item);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment