0

I have written a screen saver for my Media Centre PC (which runs Windows 8.1). It is a simple Windows Forms app which displays all the pictures in my Pictures folder randomly, captioning each picture with the folder, filename, date taken, etc. It handles the Click, MouseMove and KeyDown events, terminating if any is received.

It works fine, except that, if I press some of the keys on my Media Centre remote (like the one that displays all my recordings), the screen saver doesn't terminate. It is as if these keys don't generate a KeyDown event.

I tried putting a global keyboard hook in, but it doesn't seem to be called - I have a vague memory that these are not allowed in later versions of Windows.

Any suggestions on how I can detect all the keys on my media centre remote from my C# Windows Forms app?

The source code is on github

Cᴏʀʏ
  • 105,112
  • 20
  • 162
  • 194
Nikki Locke
  • 2,759
  • 6
  • 29
  • 53
  • Not sure how you compile a C# .scr file, so it is a Windows app. I looked up how to write a screensaver in C#, and that's what I found. – Nikki Locke Mar 06 '17 at 17:23
  • A couple of the resources I found just have MouseClick, MouseMove, and KeyPress events for the form that run `Application.Exit()`. – Cᴏʀʏ Mar 06 '17 at 17:24
  • Yes, that's what I have - and the events do not arrive for some of the keys on the media centre remote (but the keys work in media centre OK). – Nikki Locke Mar 06 '17 at 17:26
  • I tell a lie - I had forgotten I have a post-build event to copy the ,exe to .scr before deploying as a .scr. Could it be the external event processing that is eating the keys? – Nikki Locke Mar 06 '17 at 18:03

2 Answers2

0

The easiest way I can imagine is GetAsyncKeyState. https://msdn.microsoft.com/en-us/library/windows/desktop/ms646293(v=vs.85).aspx

    [DllImport( "user32.dll" )]
    static extern short GetAsyncKeyState( int KeyCode );

This works at least if your process is the foreground process (as it should be if it is a serious screen saver).

This also should handle special keys (like the media keys), as those are mostly just translated to several keyboard shortcuts.

The downside, however, is that you have to query every keyCode manually. But as you are able to catch the regular keys already, I think it would be enough to poll only the media keys.

Psi
  • 6,387
  • 3
  • 16
  • 26
  • Not sure how a function which allows me to poll for a specific key would help me determine whether _any_ key has been pressed. I suppose I could poll it in a tight loop, with every possible integer in the vKey argument, but I doubt if that is a good idea :-) – Nikki Locke Mar 06 '17 at 17:25
  • You can iteratively check every keycode (normally in the range from 1 - 255) If you detect any change there, you're fine. – Psi Mar 06 '17 at 17:25
  • I guess it would be enough to poll only the media keys as you are able to catch the other keys anyway. The only challenge is to identify their keyCodes (which should be possible using `GetAsyncKeyState` again. – Psi Mar 06 '17 at 17:36
0

Generally , I use this program to detect any key press with specific Key ID . By the way , it is written in C++ , I am sorry that I know almost nothing about C# . Let me know , If it helps or not . . Thanks @Psi :)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#if       _WIN32_WINNT < 0x0500
#undef  _WIN32_WINNT
#define _WIN32_WINNT   0x0500
#endif
#include <windows.h>
using namespace std;
int main ()
{
    char i;
    for(i=8; i<190; i++)
    {
        if(GetAsyncKeyState(i)== -32767)
        {
            cout<<int (i)<<endl;
        }
    }
    return 0;
} 
roy
  • 6,685
  • 3
  • 26
  • 39