Last active
November 26, 2019 08:41
-
-
Save WamWooWam/50a402e41a9f7c5c9039f0d6a5c40766 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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