-
Notifications
You must be signed in to change notification settings - Fork 0
/
AppCommands.cs
68 lines (58 loc) · 2.16 KB
/
AppCommands.cs
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
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
namespace MediaButtonsSend
{
//http://msdn.microsoft.com/en-us/library/dd375731%28v=VS.85%29.aspx
public static class AppCommand
{
private static ManualResetEvent _mre = new ManualResetEvent(false);
private static Form _frm;
public static void Send(AppCommandValues cmd)
{
if (_frm == null) Initialize();
_frm?.Invoke(new MethodInvoker(() => SendMessage(_frm.Handle, WM_APPCOMMAND, _frm.Handle, (IntPtr)((int)cmd << 16))));
Cleanup();
}
private static void Initialize()
{
// to be able to vork in visual studio (and other similar) running as admin we have to emulate a windows form app.
//the UAC UIPI (User Interface Privilege Isolation) kills our keybd_event when running as admin
// Run the message loop on another thread so we're compatible with a console mode app
var t = new Thread(() =>
{
_frm = new Form
{
ShowInTaskbar = false,
Visible = false,
};
var dummy = _frm.Handle;
_frm.BeginInvoke(new MethodInvoker(() => _mre.Set()));
Application.Run();
});
t.SetApartmentState(ApartmentState.STA);
t.IsBackground = true;
t.Start();
_mre.WaitOne();
}
public static void Cleanup()
{
if (_frm != null)
{
_frm.BeginInvoke(new MethodInvoker(() =>
{
_frm.Close();
Application.ExitThread();
_mre.Set();
}));
_mre.WaitOne();
_frm = null;
}
}
// Pinvoke
private const int WM_APPCOMMAND = 0x319;
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
}
}