开发者

Send key "MediaPlayPause" to an application without setting focus to it

I am creating a program that will send media key inputs (such as Med开发者_StackOverflow社区iaPlayPause, MediaNextTrack, etc) to an application that I have the IntPtr of. Sort of like a virtual remote control.

So after researching I found this, which almost tells me exactly how to solve my problem.

However, there are three problems with the approach mentioned in the link.

  1. I cannot set the application as foreground window as I need my application to be focused.
  2. They use the SendKeys function which requires the target window to be focused, goes against problem 1.
  3. From what I know, SendKeys cannot send keyboard buttons such as the keyboard Play/Pause button.

In the end, I am rather confused on what I have to use (SendInput?, SendMessage?).

Any help would be appreciated.


EDIT

Using the answer I received, I hacked together the sample code below.

Theoretically, it is supposed to find notepad and insert the letter "L" into it.

However nothing shows up on notepad, nor does the application crash. Is there an obvious error I am missing?

[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(int ZeroOnly, string lpWindowName);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, IntPtr lParam);

const int WM_KEYDOWN = 0x100;
//const int WM_KEYUP = 0x101;
const int L_KEY = 0x4C;

private void button1_Click(object sender, EventArgs e)
{
    IntPtr ip = FindWindowByCaption(0, "Untitled - Notepad");

    SendMessage(ip, WM_KEYDOWN, L_KEY, IntPtr.Zero);
    //SendMessage(ip, WM_KEYUP, L_KEY, IntPtr.Zero);
}


Most of these keys are translated to WM_APPCOMMAND* messages... so you can try SendMessage, the other option being SendInput (if the application is DirectInput-based)...

Check out the links in Windows API for common media player functions? - perhaps there is some information you can use...

As for the focus problem - there is no 100% reliable solution (see How do I send key strokes to a window without having to activate it using Windows API?)... best you can achieve with 100% reliability is to focus the application, send the keys, refocus your application... except you would write some sort of device driver (kernel mode)...


To send multimedia keys, including Play/Pause, NextTrack, PrevTrack, etc, you can use keybd_event:

public class Program
{
    public const int KEYEVENTF_EXTENTEDKEY = 1;
    public const int KEYEVENTF_KEYUP = 0;
    public const int VK_MEDIA_NEXT_TRACK = 0xB0;
    public const int VK_MEDIA_PLAY_PAUSE = 0xB3;
    public const int VK_MEDIA_PREV_TRACK = 0xB1;

    [DllImport("user32.dll")]
    public static extern void keybd_event(byte virtualKey, byte scanCode, uint flags, IntPtr extraInfo);

    public static void Main(string[] args)
    {
        keybd_event(VK_MEDIA_PLAY_PAUSE, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero);    // Play/Pause

        //keybd_event(VK_MEDIA_PREV_TRACK, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero);  // PrevTrack
        //keybd_event(VK_MEDIA_NEXT_TRACK, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero);  // NextTrack
    }

Here is a list to the supported key codes that this windows api can handle:
https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes

The SendKeys class is very nice, but it's also limited. The approach above sends the key command directly to Windows OS.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜