컨트롤 + esc 누르면 나가지는 것과 음소거까지 전부 구현한 코드입니다.
아쉽게도 크롬이나 엣지같은 웹 브라우저는 오디오 세션 pid가 본체와 분리되어 있어 음소거를 할 수 없었지만 그 외에는 다 됩니다.
물론 롤에선 제대로 작동되지 않는 부분은 못 고쳤습니다.



#include <Windows.h>

#include<stack>

#include <iostream>

#include <audiopolicy.h>

#include <mmdeviceapi.h>

#include <endpointvolume.h>


using namespace std;


void HideWindow();

void ShowWindow();

void ShowWindowAll();


stack<HWND> st = {};


char c;

HHOOK keyboardHook;

HHOOK mouseHook;


void SetApplicationVolume(DWORD processId, float volumeLevel) {

HRESULT hr = S_OK;

IMMDeviceEnumerator* enumerator = nullptr;

IMMDevice* device = nullptr;

IAudioSessionManager2* sessionManager = nullptr;

IAudioSessionEnumerator* sessionEnumerator = nullptr;


// Initialize COM library

hr = CoInitialize(nullptr);

if (FAILED(hr)) {

std::cerr << "Failed to initialize COM library" << std::endl;

return;

}


// Create multimedia device enumerator

hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), reinterpret_cast<void**>(&enumerator));

if (FAILED(hr)) {

std::cerr << "Failed to create device enumerator" << std::endl;

CoUninitialize(); // Uninitialize COM library

return;

}


// Get default audio endpoint device

hr = enumerator->GetDefaultAudioEndpoint(eRender, eConsole, &device);

if (FAILED(hr)) {

std::cerr << "Failed to get default audio endpoint device" << std::endl;

enumerator->Release();

CoUninitialize(); // Uninitialize COM library

return;

}


// Activate audio session manager

hr = device->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, nullptr, reinterpret_cast<void**>(&sessionManager));

if (FAILED(hr)) {

std::cerr << "Failed to activate audio session manager" << std::endl;

device->Release();

enumerator->Release();

CoUninitialize(); // Uninitialize COM library

return;

}


// Get session enumerator

hr = sessionManager->GetSessionEnumerator(&sessionEnumerator);

if (FAILED(hr)) {

std::cerr << "Failed to get session enumerator" << std::endl;

sessionManager->Release();

device->Release();

enumerator->Release();

CoUninitialize(); // Uninitialize COM library

return;

}


// Loop through each audio session

int sessionCount = 0;

hr = sessionEnumerator->GetCount(&sessionCount);

if (SUCCEEDED(hr)) {

for (int i = 0; i < sessionCount; ++i) {

// Get audio session control

IAudioSessionControl* sessionControl = nullptr;

hr = sessionEnumerator->GetSession(i, &sessionControl);

if (SUCCEEDED(hr)) {

// Get process ID of the audio session

DWORD sessionProcessId = 0;

IAudioSessionControl2* sessionControl2 = nullptr;

hr = sessionControl->QueryInterface(__uuidof(IAudioSessionControl2), reinterpret_cast<void**>(&sessionControl2));

if (SUCCEEDED(hr)) {

hr = sessionControl2->GetProcessId(&sessionProcessId);


cout << sessionProcessId << endl;

sessionControl2->Release();

}

if (SUCCEEDED(hr) && sessionProcessId == processId) {

// Get simple audio volume

ISimpleAudioVolume* simpleVolume = nullptr;

hr = sessionControl->QueryInterface(__uuidof(ISimpleAudioVolume), reinterpret_cast<void**>(&simpleVolume));

if (SUCCEEDED(hr)) {

// Set volume level

hr = simpleVolume->SetMasterVolume(volumeLevel, nullptr);

if (FAILED(hr)) {

std::cerr << "Failed to set volume level for session" << std::endl;

}

simpleVolume->Release();

}

}

sessionControl->Release();

}

}

}


// Release resources

sessionEnumerator->Release();

sessionManager->Release();

device->Release();

enumerator->Release();

CoUninitialize(); // Uninitialize COM library

}



LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)

{

if (nCode >= 0)

{

if (wParam == WM_XBUTTONDOWN)

{

MSLLHOOKSTRUCT* hookStruct = (MSLLHOOKSTRUCT*)lParam;

if (hookStruct->mouseData == 0x20000)

{

cout << "key : " << hookStruct->mouseData << endl;

HideWindow();

return 1; // 여기로 이동

}

else if (hookStruct->mouseData == 0x10000)

{

ShowWindow();

return 1;

}

}

else if (wParam == WM_XBUTTONUP)

{

return 1;

}

}

return CallNextHookEx(mouseHook, nCode, wParam, lParam); // 이전으로 돌아가도록 변경

}


LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)

{

if (nCode >= 0)

{

KBDLLHOOKSTRUCT* kbStruct = (KBDLLHOOKSTRUCT*)lParam;


if (wParam == WM_KEYDOWN)

{

// F1 키를 누른 경우

if (kbStruct->vkCode == VK_F1)

{

ShowWindowAll();

return 1;

}

else if (kbStruct->vkCode == VK_ESCAPE && GetAsyncKeyState(VK_CONTROL) & 0x8000)

{

ShowWindow(GetConsoleWindow(), SW_SHOW);

ShowWindowAll();

UnhookWindowsHookEx(keyboardHook);

UnhookWindowsHookEx(mouseHook);

PostQuitMessage(0);

return 1;

}

else

{

// 다른 키를 누른 경우에는 처리를 계속합니다.

std::cout << "Key pressed: " << kbStruct->vkCode << std::endl;

}

}

if (wParam == WM_KEYUP&&kbStruct->vkCode==VK_F1)

{

return 1;

}

}

// 후킹된 이벤트 처리를 계속합니다.

return CallNextHookEx(keyboardHook, nCode, wParam, lParam);

}


int main()

{

ShowWindow(GetConsoleWindow(), SW_HIDE);

keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, 0);


HINSTANCE hInstance = GetModuleHandle(NULL);

mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, NULL, 0);

if (mouseHook == NULL) {

std::cerr << "Failed to install mouse hook!" << std::endl;

return 1;

}

MSG msg;

while (GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

UnhookWindowsHookEx(keyboardHook);

UnhookWindowsHookEx(mouseHook);

}


bool func(char* a)

{

return strcmp(a, "Shell_TrayWnd")&& strcmp(a, "Progman");

}


void HideWindow()

{

HWND hWnd;

POINT point;


GetCursorPos(&point);

hWnd = WindowFromPoint(point);


char clsName_v[256]; 

HWND parent = GetParent(hWnd), parent2;

while (1) {

parent2 = GetParent(parent);

if (parent2 == 0)

break;

parent = parent2;

}


if (parent != 0)

hWnd = parent;


GetClassNameA(hWnd, clsName_v, 256);

std::cout << hWnd << "\n";

std::cout << clsName_v << "\n";

if (func(clsName_v))

{

st.push(hWnd);

ShowWindow(hWnd, SW_HIDE);

DWORD processId;

GetWindowThreadProcessId(hWnd, &processId);

SetApplicationVolume(processId, 0.0f);

}

}


void ShowWindowAll()

{

while (!st.empty())

{

ShowWindow();

}

}


void ShowWindow()

{

if (!st.empty())

{

DWORD processId;

GetWindowThreadProcessId(st.top(), &processId);

SetApplicationVolume(processId, 1.0f);

ShowWindow(st.top(), SW_SHOW);

st.pop();

}

}