1
1
using System ;
2
+ using System . Collections ;
2
3
using System . Collections . Generic ;
3
4
using System . Drawing ;
4
5
using System . Linq ;
@@ -14,10 +15,15 @@ namespace tb_vol_scroll.Forms
14
15
public partial class AudioPlaybackDevicesForm : Form
15
16
{
16
17
private bool isRefreshing = false ;
18
+
19
+ private Queue updateDeviceTaskQueue = new Queue ( ) ;
20
+ private Task updateDeviceTask = null ;
21
+
22
+
17
23
public AudioPlaybackDevicesForm ( )
18
24
{
19
25
InitializeComponent ( ) ;
20
- Utils . SetWindowTheme ( DevicesListView . Handle , "Explorer" , null ) ;
26
+ // Utils.SetWindowTheme(DevicesListView.Handle, "Explorer", null);
21
27
22
28
}
23
29
@@ -46,24 +52,31 @@ private async void AudioPlaybackDevicesForm_Shown(object sender, EventArgs e)
46
52
await LoadAudioPlaybackDevicesList ( ) ;
47
53
}
48
54
49
- public async Task LoadAudioPlaybackDevicesList ( )
55
+ private async Task ProcessUpdateDeviceQueue ( )
50
56
{
51
- Utils . InvokeIfRequired ( this , ( ) =>
57
+ if ( ( updateDeviceTask == null ) || updateDeviceTask . IsCompleted )
52
58
{
53
- SuspendLayout ( ) ;
54
- DevicesListView . Items . Clear ( ) ;
55
- SetDefaultButton . Enabled = false ;
56
- RefreshButton . Enabled = false ;
57
- } ) ;
59
+ if ( updateDeviceTaskQueue . Count != 0 )
60
+ {
61
+ updateDeviceTaskQueue . Dequeue ( ) ;
62
+ updateDeviceTask = RefreshOnDeviceActivity ( ) ;
63
+ await updateDeviceTask ;
64
+ if ( updateDeviceTaskQueue . Count != 0 )
65
+ await ProcessUpdateDeviceQueue ( ) ;
66
+ }
67
+ }
68
+ }
58
69
70
+ public async Task LoadAudioPlaybackDevicesList ( )
71
+ {
59
72
List < ListViewItem > deviceListViewItem = new List < ListViewItem > ( ) ;
60
73
List < CoreAudioDevice > audioDevices = ( await Task . Run ( ( ) => Globals . AudioHandler . AudioController . GetPlaybackDevicesAsync ( DeviceState . Active ) ) ) . ToList ( ) ;
61
74
if ( audioDevices . Count != 0 )
62
75
{
63
76
foreach ( CoreAudioDevice d in audioDevices )
64
77
{
65
- Utils . ExtractIconEx ( d . IconPath . Split ( ',' ) [ 0 ] , int . Parse ( d . IconPath . Split ( ',' ) [ 1 ] ) , out IntPtr hIcon , IntPtr . Zero , 1 ) ;
66
- DevicesListViewImageList . Images . Add ( Icon . FromHandle ( hIcon ) ) ;
78
+ Icon iconImg = Utils . GetIconFromResource ( d . IconPath ) ;
79
+ DevicesListViewImageList . Images . Add ( iconImg ) ;
67
80
ListViewItem deviceItem = new ListViewItem
68
81
{
69
82
ImageIndex = audioDevices . IndexOf ( d ) ,
@@ -80,92 +93,99 @@ public async Task LoadAudioPlaybackDevicesList()
80
93
Utils . InvokeIfRequired ( this , ( ) =>
81
94
{
82
95
DevicesListView . Items . AddRange ( deviceListViewItem . ToArray ( ) ) ;
83
- RefreshButton . Enabled = true ;
84
96
bool hasScrollBars = DevicesListView . ClientSize . Height < ( DevicesListView . Items . Count + 1 ) * DevicesListView . Items [ 0 ] . Bounds . Height ;
85
97
DevicesListView . Columns [ 0 ] . Width = DevicesListView . Width - ( 60 * 3 ) - ( hasScrollBars ? 25 : 0 ) ;
86
- ResumeLayout ( ) ;
98
+ RefreshButton . Enabled = true ;
87
99
} ) ;
88
100
}
89
101
90
102
private async void SetDefaultButton_Click ( object sender , EventArgs e )
91
103
{
92
- if ( DevicesListView . SelectedItems . Count == 0 )
104
+ if ( DevicesListView . SelectedItems . Count == 1 )
93
105
{
94
106
CoreAudioDevice newPlaybackDevice = ( CoreAudioDevice ) DevicesListView . SelectedItems [ 0 ] . Tag ;
107
+ DevicesListView . SelectedItems . Clear ( ) ;
95
108
await newPlaybackDevice . SetAsDefaultAsync ( ) ;
96
109
}
97
- SetDefaultButton . Enabled = false ;
110
+ MakeDefaultButton . Enabled = false ;
98
111
}
99
112
100
113
public async Task RefreshOnDeviceActivity ( )
101
114
{
102
- if ( ! isRefreshing )
115
+ List < CoreAudioDevice > audioDevices = ( await Task . Run ( ( ) => Globals . AudioHandler . AudioController . GetPlaybackDevicesAsync ( DeviceState . Active ) ) ) . ToList ( ) ;
116
+ Utils . InvokeIfRequired ( this , ( ) =>
103
117
{
104
- isRefreshing = true ;
105
- List < CoreAudioDevice > audioDevices = ( await Task . Run ( ( ) => Globals . AudioHandler . AudioController . GetPlaybackDevicesAsync ( DeviceState . Active ) ) ) . ToList ( ) ;
106
- Utils . InvokeIfRequired ( this , ( ) =>
118
+ RefreshButton . Enabled = false ;
119
+ foreach ( ListViewItem deviceItem in DevicesListView . Items )
107
120
{
108
- foreach ( ListViewItem deviceItem in DevicesListView . Items )
121
+ if ( audioDevices . Contains ( deviceItem . Tag ) )
109
122
{
110
- if ( audioDevices . Contains ( deviceItem . Tag ) )
111
- {
112
- deviceItem . SubItems [ 1 ] . Text = $ "{ ( int ) Math . Round ( ( ( CoreAudioDevice ) deviceItem . Tag ) . Volume ) } %";
113
- deviceItem . SubItems [ 2 ] . Text = ( ( CoreAudioDevice ) deviceItem . Tag ) . IsDefaultDevice ? "Yes" : "No" ;
114
- deviceItem . SubItems [ 3 ] . Text = ( ( CoreAudioDevice ) deviceItem . Tag ) . IsMuted ? "Yes" : "No" ;
115
- deviceItem . BackColor = ( ( CoreAudioDevice ) deviceItem . Tag ) . IsDefaultDevice ? Color . FromArgb ( 225 , 255 , 225 ) : Color . White ;
116
- }
117
- else
118
- deviceItem . Remove ( ) ;
119
- audioDevices . Remove ( ( CoreAudioDevice ) deviceItem . Tag ) ;
123
+ deviceItem . SubItems [ 1 ] . Text = $ "{ ( int ) Math . Round ( ( ( CoreAudioDevice ) deviceItem . Tag ) . Volume ) } %";
124
+ deviceItem . SubItems [ 2 ] . Text = ( ( CoreAudioDevice ) deviceItem . Tag ) . IsDefaultDevice ? "Yes" : "No" ;
125
+ deviceItem . SubItems [ 3 ] . Text = ( ( CoreAudioDevice ) deviceItem . Tag ) . IsMuted ? "Yes" : "No" ;
126
+ deviceItem . BackColor = ( ( CoreAudioDevice ) deviceItem . Tag ) . IsDefaultDevice ? Color . FromArgb ( 225 , 255 , 225 ) : Color . White ;
120
127
}
121
- if ( audioDevices . Count != 0 )
128
+ else
129
+ deviceItem . Remove ( ) ;
130
+ audioDevices . Remove ( ( CoreAudioDevice ) deviceItem . Tag ) ;
131
+ }
132
+ if ( audioDevices . Count != 0 )
133
+ {
134
+ foreach ( CoreAudioDevice device in audioDevices )
122
135
{
123
- foreach ( CoreAudioDevice device in audioDevices )
136
+ ListViewItem deviceItem = new ListViewItem
124
137
{
125
- ListViewItem deviceItem = new ListViewItem
126
- {
127
- Text = device . FullName
128
- } ;
129
- deviceItem . SubItems . Add ( $ "{ ( int ) Math . Round ( device . Volume ) } %") ;
130
- deviceItem . SubItems . Add ( device . IsDefaultDevice ? "Yes" : "No" ) ;
131
- deviceItem . SubItems . Add ( device . IsMuted ? "Yes" : "No" ) ;
132
- deviceItem . BackColor = device . IsDefaultDevice ? Color . FromArgb ( 230 , 255 , 230 ) : Color . White ;
133
- deviceItem . Tag = device ;
134
- DevicesListView . Items . Add ( deviceItem ) ;
135
- }
138
+ Text = device . FullName
139
+ } ;
140
+ deviceItem . SubItems . Add ( $ "{ ( int ) Math . Round ( device . Volume ) } %") ;
141
+ deviceItem . SubItems . Add ( device . IsDefaultDevice ? "Yes" : "No" ) ;
142
+ deviceItem . SubItems . Add ( device . IsMuted ? "Yes" : "No" ) ;
143
+ deviceItem . BackColor = device . IsDefaultDevice ? Color . FromArgb ( 230 , 255 , 230 ) : Color . White ;
144
+ deviceItem . Tag = device ;
145
+ DevicesListView . Items . Add ( deviceItem ) ;
136
146
}
137
- DevicesListViewImageList . Images . Clear ( ) ;
138
- foreach ( ListViewItem deviceItem in DevicesListView . Items )
139
- {
140
- CoreAudioDevice audioDevice = ( ( CoreAudioDevice ) deviceItem . Tag ) ;
141
- Utils . ExtractIconEx ( audioDevice . IconPath . Split ( ',' ) [ 0 ] , int . Parse ( audioDevice . IconPath . Split ( ',' ) [ 1 ] ) , out IntPtr hIcon , IntPtr . Zero , 1 ) ;
142
- DevicesListViewImageList . Images . Add ( Icon . FromHandle ( hIcon ) ) ;
143
- deviceItem . ImageIndex = DevicesListView . Items . IndexOf ( deviceItem ) ;
147
+ }
148
+ DevicesListViewImageList . Images . Clear ( ) ;
149
+ foreach ( ListViewItem deviceItem in DevicesListView . Items )
150
+ {
151
+ CoreAudioDevice audioDevice = ( CoreAudioDevice ) deviceItem . Tag ;
152
+ Icon iconImg = Utils . GetIconFromResource ( audioDevice . IconPath ) ;
153
+ DevicesListViewImageList . Images . Add ( iconImg ) ;
154
+ deviceItem . ImageIndex = DevicesListView . Items . IndexOf ( deviceItem ) ;
144
155
145
- }
146
156
bool hasScrollBars = DevicesListView . ClientSize . Height < ( DevicesListView . Items . Count + 1 ) * DevicesListView . Items [ 0 ] . Bounds . Height ;
147
157
DevicesListView . Columns [ 0 ] . Width = DevicesListView . Width - ( 60 * 3 ) - ( hasScrollBars ? 25 : 0 ) ;
158
+ RefreshButton . Enabled = true ;
159
+
160
+ }
161
+ } ) ;
162
+ }
163
+
164
+ public async Task OnDeviceChanged ( )
165
+ {
166
+ if ( updateDeviceTaskQueue . Count == 0 )
167
+ updateDeviceTaskQueue . Enqueue ( null ) ;
168
+ if ( updateDeviceTaskQueue . Count != 0 )
169
+ await ProcessUpdateDeviceQueue ( ) ;
170
+
148
171
149
- } ) ;
150
- isRefreshing = false ;
151
- }
152
172
}
153
173
154
174
155
175
private async void RefreshButton_Click ( object sender , EventArgs e )
156
176
{
157
- await RefreshOnDeviceActivity ( ) ;
177
+ await OnDeviceChanged ( ) ;
158
178
}
159
179
160
180
private void AudioPlaybackDevicesForm_Deactivate ( object sender , EventArgs e )
161
181
{
162
- if ( ! isRefreshing )
163
182
Close ( ) ;
164
183
}
165
184
166
185
private void DevicesListView_SelectedIndexChanged ( object sender , EventArgs e )
167
186
{
168
- SetDefaultButton . Enabled = DevicesListView . SelectedItems . Count == 1 ;
187
+ MakeDefaultButton . Enabled = DevicesListView . SelectedItems . Count == 1 ;
188
+ Utils . AvoidControlFocus ( DevicesListView . Handle ) ;
169
189
}
170
190
171
191
private async void DevicesListView_DoubleClick ( object sender , EventArgs e )
@@ -178,5 +198,11 @@ private async void DevicesListView_DoubleClick(object sender, EventArgs e)
178
198
Close ( ) ;
179
199
}
180
200
}
201
+
202
+ private void AudioPlaybackDevicesForm_FormClosing ( object sender , FormClosingEventArgs e )
203
+ {
204
+ updateDeviceTaskQueue . Clear ( ) ;
205
+ updateDeviceTask = null ;
206
+ }
181
207
}
182
208
}
0 commit comments