-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVolumeControl.cs
More file actions
144 lines (125 loc) · 4.53 KB
/
Copy pathVolumeControl.cs
File metadata and controls
144 lines (125 loc) · 4.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using System;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using CSCore.CoreAudioAPI;
using MaterialSkin.Controls;
namespace AutoVolumeControl
{
class VolumeControl : ApplicationContext
{
private readonly AppSettings appSettings;
private readonly Apps apps;
private readonly NotifyIcon notifyIcon;
private MMDevice defaultPlaybackDevice;
private AudioEndpointVolumeCallback volumeCallback;
private AudioEndpointVolume defaultDeviceVolume;
private readonly Control uiControl;
private readonly MenuHandler menuHandler;
public VolumeControl()
{
uiControl = new Control();
uiControl.CreateControl();
appSettings = new AppSettings();
apps = new Apps();
apps.AppsUpdated += OnAppsUpdated;
notifyIcon = CreateNotifyIcon(); menuHandler = new MenuHandler((MaterialContextMenuStrip)notifyIcon.ContextMenuStrip, appSettings, apps);
menuHandler.OnExit(Exit);
InitializeDefaultDevice();
}
private NotifyIcon CreateNotifyIcon()
{
var icon = new NotifyIcon
{
Icon = Properties.Resources.icon,
ContextMenuStrip = new MaterialContextMenuStrip(),
Visible = true
};
return icon;
}
private void InitializeDefaultDevice()
{
Task.Run(() =>
{
try
{
InitializeCom();
using var enumerator = new MMDeviceEnumerator();
var playbackDevice = enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
var deviceVolume = AudioEndpointVolume.FromDevice(playbackDevice);
var volumeCallback = new AudioEndpointVolumeCallback(playbackDevice, appSettings, apps);
deviceVolume.RegisterControlChangeNotify(volumeCallback);
AssignDeviceVariables(playbackDevice, deviceVolume, volumeCallback);
}
catch (Exception ex)
{
ShowError(ex.Message);
}
finally
{
ComHelper.CoUninitialize();
}
});
}
private void InitializeCom()
{
int hr = ComHelper.CoInitializeEx(IntPtr.Zero, ComHelper.COINIT.COINIT_MULTITHREADED);
if (hr == (int)ComHelper.HResult.RPC_E_CHANGED_MODE)
{
Console.WriteLine("COM already initialized with a different threading model in VolumeControl");
}
else if (hr < 0)
{
throw new COMException("Failed to initialize COM library", hr);
}
}
private void AssignDeviceVariables(MMDevice playbackDevice, AudioEndpointVolume deviceVolume, AudioEndpointVolumeCallback callback)
{
uiControl.BeginInvoke((Action)(() =>
{
defaultPlaybackDevice = playbackDevice;
defaultDeviceVolume = deviceVolume;
volumeCallback = callback;
apps.Refresh();
}));
}
private void ShowError(string message)
{
uiControl.BeginInvoke((Action)(() =>
{
notifyIcon.BalloonTipText = $"Error initializing default playback device: {message}";
notifyIcon.ShowBalloonTip(5000);
}));
}
private void OnAppsUpdated(object sender, EventArgs e)
{
uiControl.BeginInvoke((Action)(() =>
{
menuHandler.Generate();
}));
}
public void Exit(object sender, EventArgs e)
{
Dispose();
Application.ExitThread();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
defaultDeviceVolume?.UnregisterControlChangeNotify(volumeCallback);
volumeCallback?.Dispose();
defaultDeviceVolume?.Dispose();
defaultPlaybackDevice?.Dispose();
apps?.Dispose();
if (notifyIcon != null)
{
notifyIcon.Visible = false;
notifyIcon.Dispose();
}
uiControl?.Dispose();
}
base.Dispose(disposing);
}
}
}