WPF(C#): Controller Right Joystick to Arrow Keys - c#

I'm using SharpDx and X-input to get my Xbox Controller's input but I'm having trouble finding to simulate the right arrow key when I move my right joystick right. This is what I got so far. My issue is when I move the stick to the right it presses the arrow key more than once so I tried to set up a thread.sleep to make it press every second but did not work. Kinda running out of ideas and would really appreciate some help.
public class XboxController
{
private const int V = 2_000;
private Controller _controller;
private IMouseSimulator _mouseSimulator;
private IKeyboardSimulator _keyboardSimulator;
private Timer _timer;
private bool _wasADown;
public int deadband = 2500;
private const int RefreshRate = 60;
public XboxController()
{
_controller = new SharpDX.XInput.Controller(UserIndex.One);
_mouseSimulator = new InputSimulator().Mouse;
_keyboardSimulator = new InputSimulator().Keyboard;
_timer = new Timer(obj => Update());
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += timer_Tick;
timer.Start();
}
private void timer_Tick(object sender, EventArgs e)
{
}
public void Start()
{
_timer.Change(0, 1000 / RefreshRate);
}
private void Update()
{
_controller.GetState(out var state);
Movement(state);
Scroll(state);
LeftButton(state);
RightButton(state);
Stick(state);
}
private void RightButton(State state)
{
if (state.Gamepad.Buttons == GamepadButtonFlags.B)
{
_keyboardSimulator.KeyPress(WindowsInput.Native.VirtualKeyCode.BACK);
Thread.Sleep(1000);
}
}
private void LeftButton(State state)
{
var isADown = state.Gamepad.Buttons.HasFlag(GamepadButtonFlags.A);
if (isADown && !_wasADown) _mouseSimulator.LeftButtonDown();
if (!isADown && _wasADown) _mouseSimulator.LeftButtonUp();
_wasADown = isADown;
}
private void Scroll(State state)
{
var x = state.Gamepad.RightThumbX / 10000;
var y = state.Gamepad.RightThumbY / 10000;
_mouseSimulator.HorizontalScroll(x);
_mouseSimulator.VerticalScroll(y);
}
private void Movement(State state)
{
var x = state.Gamepad.LeftThumbX / 2500;
var y = state.Gamepad.LeftThumbY / 2500;
_mouseSimulator.MoveMouseBy(x, -y);
}
private void Stick(State state)
{
while ((state.Gamepad.RightThumbX) > 0)
{
Thread.Sleep(1000);
_keyboardSimulator.KeyPress(WindowsInput.Native.VirtualKeyCode.RIGHT);
Thread.Sleep(1000);
}
}
}
}

Related

Restart InActivity Monitor after timer is stopped

I have WinForms App where I am using the code in this following Post to check the InActivity Status of my app (Please see the accepted answer in the post). InActivity In WinForms. Once the app reaches inactivity its stopping the inactivity monitor. But then I want to restart the time once the user logs in.
So I have a notification mechanism when the user logs in and I am calling the start timer method again. I get the Started Monitor Message but the app never tracks inactivity and I don't get Timer reporting app is InACTIVE message at all. Please help.
public static System.Windows.Forms.Timer IdleTimer =null;
static int MilliSeconds = 60000;
static void Main(string[] args)
{
f = new GeneStudyForm(true, arguments.SystemTimeOutFolder, arguments.SystemTimeOutFile, StartInActivityMonitor);
int x = StartInActivityMonitor();
}
public static void StartInActivityMonitor()
{
IdleTimer = new Timer();
LeaveIdleMessageFilter limf = new LeaveIdleMessageFilter();
Application.AddMessageFilter(limf);
IdleTimer.Interval = MilliSeconds; //One minute; change as needed
Application.Idle += new EventHandler(Application_Idle);
if (IdleTimer != null)
{
MessageBox.Show(IdleTimer.Interval.ToString());
}
IdleTimer.Tick += TimeDone;
IdleTimer.Tag = InActivityTimer.Started;
MessageBox.Show("starting");
IdleTimer.Start();
}
static private void Application_Idle(object sender, EventArgs e)
{
if (!IdleTimer.Enabled) // not yet idling?
IdleTimer.Start();
}
static private void TimeDone(object sender, EventArgs e)
{
try
{
MessageBox.Show("Stopped");
IdleTimer.Stop(); // not really necessary
f.MonitorDirectory();
f.UpdateInActivityStatus();
IdleTimer.Tick -= TimeDone;
Application.Idle -= new EventHandler(Application_Idle);
}
catch(Exception ex)
{
MessageBox.Show(ex.InnerException + ex.Data.ToString());
}
}
Here is my GeneStudyForm
public partial class GeneStudyForm
{
GeneStudySystemTimeOutIO GeneStudyIO;
Func<int> StartTimer;
//Passing the StartInActivityMonitor Method as Func Delegate
public GeneStudyForm(bool isStandalone, string TimeOutFolder, string TimeOutFile, System.Func<int> MyMethod)
{
GeneStudyIO = GeneStudySystemTimeOutIO.GetInstance(TimeOutFolder, TimeOutFile);
UpdateActivityStatus(AppName.GeneStudyStatus, ActivityStatus.Active);
this.StartTimer = MyMethod;
}
public void UpdateActivityStatus(AppName name, ActivityStatus status)
{
if (GeneStudyIO != null)
{
GeneStudyIO.WriteToFile(name, status);
}
}
public void MonitorDirectory()
{
FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(GeneStudyIO.GetDriectory());
fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite;
fileSystemWatcher.Filter = "*.json";
fileSystemWatcher.Changed += FileSystemWatcher_Changed;
fileSystemWatcher.EnableRaisingEvents = true;
}
public void UnRegister(FileSystemWatcher fileSystemWatcher)
{
fileSystemWatcher.Changed -= FileSystemWatcher_Changed;
}
// I am writing the inactive status to a file. So this event will fill
private void FileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
{
try
{
var root = GeneStudyIO.GetDesrializedJson();
if (root != null && root.AllApplications != null)
{
var item = root.AllApplications.Any(x => x.Status == ActivityStatus.Active.ToString());
if (!item)
{
if (InActivecount == 0)
{
GeneStudyAndApplicationCommon.TimeStatus = InActivityTimer.Ended;
MessageBox.Show("I am hiding");
this.Hide();
InActivecount++;
}
}
else
{
if (GeneStudyAndApplicationCommon.TimeStatus == InActivityTimer.Ended)
{
MessageBox.Show("I am showing");
this.Show();
UnRegister(sender as FileSystemWatcher);
UpdateActivityStatus(AppName.GeneStudyStatus, ActivityStatus.Active);
MessageBox.Show("Updated Status");
if (StartTimer != null)
{
MessageBox.Show("Starting Timer again");
if (StartTimer() == -1)
{
MessageBox.Show("Couldn't start timer");
}
}
}
}
}
}
catch (Exception ex)
{
SystemDebugLogLogger.LogException(ex);
}
}
}
This soulution is quite different from what I have posted. But I could solve my problem with this. But I want to post it if it helps someone. Here is the post I am following Last User Input
I created a class called IdleCheck where I am getting LastUserInput as follows
public static class IdleCheck
{
[StructLayout(LayoutKind.Sequential)]
private struct LASTINPUTINFO
{
[MarshalAs(UnmanagedType.U4)]
public int cbSize;
[MarshalAs(UnmanagedType.U4)]
public int dwTime;
}
[DllImport("user32.dll")]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO x);
public static int GetLastInputTime()
{
var inf = new LASTINPUTINFO();
inf.cbSize = Marshal.SizeOf(inf);
inf.dwTime = 0;
return (GetLastInputInfo(ref inf)) ? Environment.TickCount - inf.dwTime : 0;
}
}
Next in the actual Form this is my code. I am using a simple yes no message box to see if the timer can be stopped and recalled again when needed. You can apply your own locking mechanism.
I want the app to time out if it is InActive for 20 seconds. Change it as needed.
public partial class Form1 : Form
{
Timer timer;
const int TIMEOUT_DONE = 20000;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Reset();
}
void timer_Tick(object sender, EventArgs e)
{
//var ms = TIMEOUT_DONE - IdleCheck.GetLastInputTime();
if (IdleCheck.GetLastInputTime() > TIMEOUT_DONE)
{
DialogResult dialogResult = MessageBox.Show("Sure", "Some Title", MessageBoxButtons.YesNo);
if (dialogResult == DialogResult.Yes)
{
Stop();
Reset();
}
}
}
public void Reset()
{
timer = new Timer();
timer.Interval = 10000;
timer.Tick += timer_Tick;
timer.Start();
}
public void Stop()
{
timer.Tick -= timer_Tick;
timer.Stop();
}
}

Timer is not working truely

Timer is working only one time. This service must be work in every 2minutes...
public partial class Service1 : ServiceBase
{
RuleContext entity = new RuleContext();
private int id;
private Timer _timer;
private DateTime _lastRun = DateTime.Now.AddDays(-1);
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
OnTimer();
}
public void OnTimer()
{
Timeout.Infinite);
_timer = new Timer();
_timer.Interval = 2 * 60 * 1000;
_timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
_timer.Enabled = true;
_timer.AutoReset = true;
_timer.Start();
}
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
// ignore the time, just compare the date
if (_lastRun.Date <= DateTime.Now.Date)
{
GetRule();
}
}
protected override void OnStop()
{
}
public void GetRule()
{
var query = from ruleset in entity.RuleSets
join rule in entity.Rules on ruleset.Id equals rule.RuleSetId
join schedulerule in entity.Schedules on rule.ScheduleId equals schedulerule.Id
select new
{
Id = ruleset.Id,
daily = schedulerule.Daily,
mountly = schedulerule.Monthly,
dayofMounth = schedulerule.DayOfMonth,
};
foreach (var q in query.ToList())
{
if (q.mountly && q.daily)
{
if (q.dayofMounth == (int)DateTime.Now.Day)
{
UpdateValue(q.Id);
}
}
else if (q.daily)
{
UpdateValue(q.Id);
}
else if (q.mountly)
{
if (q.dayofMounth == (int)DateTime.Now.Day)
{
UpdateValue(q.Id);
}
}
}
}
public void UpdateValue(int id)
{
var ruleSet = entity.RuleSets.First(k => k.Id == id);
ruleSet.RcvByte = 0;
ruleSet.SentByte = 0;
entity.SaveChanges();
}
}
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
// ignore the time, just compare the date
if (_lastRun.Date <= DateTime.Now.Date)
{
GetRule();
}
}
Since the AutoReset property is set to true, no need to Stop and Start timer.
_timer.Stop();
this line is causing this problem. Remove it

C# Tasks - am I experiencing a suspicious increasing of number of handles

I am dipping my toes in Tasks (.NET 4.5) and am experiencing increasing handles (in task manager). I have a class doing a simple Play/Stop of audio file using MediaPlayer class (System.Windows.Media namespace). I have a second class which wraps it and exposes sync/async playback.
All is working fine and functionality is OK, but see the number of handles increasing in Task manager which worries me.... Am I doing something wrong here?
Important note: if I comment our the "await Task.Delay(1000);" --> then all is just fine and no leaks are observed... How come??
public partial class Form1 : Form
{
AudioActions syncAction = new AudioActions(#"c:\1.wav", false);
AudioActions asyncAction = new AudioActions(#"c:\1.wav", true);
public Form1()
{
InitializeComponent();
}
private async void syncPlayback(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++)
{
await syncAction.Start();
}
}
private async void asyncPlayback(object sender, EventArgs e)
{
for (int i = 0; i < 100; i++)
{
await asyncAction.Start();
await Task.Delay(100); //remove this line and all is fine!!!!
asyncAction.Stop();
}
Console.WriteLine("done");
}
}
public class AudioActions
{
private Audio audio = null;
private TaskCompletionSource<bool> tcs = null;
private string pathToWaveFile;
private bool async;
public AudioActions(string pathToWaveFile, bool async)
{
this.pathToWaveFile=pathToWaveFile;
this.async=async;
}
public Task Start()
{
tcs = new TaskCompletionSource<bool>();
audio = new Audio();
audio.mediaPlayerPlaybackStoppedEvent += Audio_wmPlaybackStopped;
if (async)
tcs.TrySetResult(true); //since its async operation, lets return immediately and free the task from waiting
audio.PlayAudioFileInMediaPlayer(pathToWaveFile);
return tcs.Task;
}
private void Audio_wmPlaybackStopped()
{
audio.mediaPlayerPlaybackStoppedEvent -= Audio_wmPlaybackStopped;
tcs.TrySetResult(true); //playback stopped. Lets free the task from waiting
}
public void Stop()
{
audio.StopAudioFilePlaybackInMediaPlayer();
}
}
public class Audio
{
MediaPlayer mediaPlayer = null;
public delegate void MediaPlayerPlaybackStoppedDelegate();
public event MediaPlayerPlaybackStoppedDelegate mediaPlayerPlaybackStoppedEvent;
public void PlayAudioFileInMediaPlayer(string pathToWavFile)
{
mediaPlayer = new MediaPlayer();
mediaPlayer.MediaEnded += mediaPlayer_MediaEnded;
mediaPlayer.Open(new Uri(pathToWavFile));
mediaPlayer.Play();
}
void mediaPlayer_MediaEnded(object sender, EventArgs e)
{
mediaPlayerPlaybackStoppedEvent.Invoke();
MediaPlayer mediaPlayer = (MediaPlayer)sender;
mediaPlayer.MediaEnded -= mediaPlayer_MediaEnded;
mediaPlayer.Close();
mediaPlayer = null;
}
public void StopAudioFilePlaybackInMediaPlayer()
{
mediaPlayer.Stop();
mediaPlayer.Close();
mediaPlayer = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}
Adding a strip down code:
private async void asyncPlayback(object sender, EventArgs e)
{
AudioActions asyncAction = new AudioActions();
for (int i = 0; i < 100; i++)
{
await asyncAction.Start();
await Task.Delay(1000); //remove this line and all is fine!!!!
asyncAction.Stop();
}
}
public class AudioActions
{
private Audio audio = null;
private TaskCompletionSource<bool> tcs = null;
public Task Start()
{
tcs = new TaskCompletionSource<bool>();
audio = new Audio();
tcs.TrySetResult(true); //since its async operation, lets return immediately and free the task from waiting
audio.PlayAudioFileInMediaPlayer(#"c:\1.wav");
return tcs.Task;
}
public void Stop()
{
audio.StopAudioFilePlaybackInMediaPlayer();
}
}
public class Audio
{
MediaPlayer mediaPlayer = null;
public void PlayAudioFileInMediaPlayer(string pathToWavFile)
{
mediaPlayer = new MediaPlayer();
mediaPlayer.Open(new Uri(pathToWavFile));
mediaPlayer.Play();
}
public void StopAudioFilePlaybackInMediaPlayer()
{
mediaPlayer.Stop();
mediaPlayer.Close();
mediaPlayer = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}
Modified class solving the problem:
public class Audio
{
public delegate void NaudioPlaybackStoppedDelegate();
public event NaudioPlaybackStoppedDelegate naudioPlaybackStoppedEvent;
private WaveOut player = null;
public void PlayAudioFileUsingNaudio(string pathToWavFile)
{
player = new WaveOut();
AudioFileReader waveFileReader = new AudioFileReader(pathToWavFile);
player.Init(waveFileReader);
player.PlaybackStopped += NAudio_Stopped;
player.Play();
}
private void NAudio_Stopped(object sender, StoppedEventArgs e)
{
player.PlaybackStopped -= NAudio_Stopped;
if (naudioPlaybackStoppedEvent!=null)
naudioPlaybackStoppedEvent.Invoke();
player.Dispose();
}
public void StopAudioFilePlaybackInNaudio()
{
player.Stop();
}
}
Replacing MediaPlayer with NAudio 3rd party solved it.
public class Audio
{
public delegate void NaudioPlaybackStoppedDelegate();
public event NaudioPlaybackStoppedDelegate naudioPlaybackStoppedEvent;
private WaveOut player = null;
public void PlayAudioFileUsingNaudio(string pathToWavFile)
{
player = new WaveOut();
AudioFileReader waveFileReader = new AudioFileReader(pathToWavFile);
player.Init(waveFileReader);
player.PlaybackStopped += NAudio_Stopped;
player.Play();
}
private void NAudio_Stopped(object sender, StoppedEventArgs e)
{
player.PlaybackStopped -= NAudio_Stopped;
if (naudioPlaybackStoppedEvent!=null)
naudioPlaybackStoppedEvent.Invoke();
player.Dispose();
}
public void StopAudioFilePlaybackInNaudio()
{
player.Stop();
}
}

c# Unit test a delegate event handler

I have a CountDownTimer class that updates a controller that updates the user interface. The problem i have is when i run my unit tests i get a NllReferenceException because the event handlder(Tick) is never initialized always null. What is the best possible solution to this problem? Or should i go about it differently. Thanks
public class CountDownTimer : ICountDownTimer
{
private int seconds; // Time in seconds
private int reSetValue; // Time in seconds
private System.Windows.Forms.Timer timer1;
public event TickHandler Tick;
public EventArgs e = null;
public delegate void TickHandler(CountDownTimer m, EventArgs e, int seconds);
public CountDownTimer(int seconds)
{
this.seconds = seconds;
reSetValue = seconds;
timer1 = new System.Windows.Forms.Timer();
timer1.Tick += new EventHandler(timer1_Tick); // Add Handler(timer1_Tick)
timer1.Interval = 1000; // 1 second
}
private void timer1_Tick(object sender, EventArgs e)
{
CallTickHandler();
if (getSeconds() == 0) // Stop Timer at 0
{
timer1.Stop(); // Stop timer
}
else
{
if (getSeconds() % 60 == 0 || getSeconds() >= 1 && getSeconds() <= 10)
{
CallTickHandler();
}
}
seconds--; // Decrement seconds
}
public void StartTimer()
{
timer1.Start();
}
public void StopTimer()
{
timer1.Stop();
}
public void ResetTimer()
{
timer1.Stop();
seconds = reSetValue;
CallTickHandler();
}
public void SetTimer(int seconds)
{
timer1.Stop();
this.seconds = getSeconds();
reSetValue = getSeconds();
CallTickHandler();
}
internal void CallTickHandler()
{
Tick(this, e, getSeconds());
}
public Boolean isEnabled()
{
return timer1.Enabled;
}
public int getSeconds()
{
return seconds;
}
}
public class Controller : ApplicationContext
{
//Store a reference to the UI
internal frmMain MainUI { get; set; }
private int seconds = 300;
CountDownTimer timer;
public Controller()
{
MainUI = new frmMain(this);
//We can do any necessary checks or changes to the MainUI here before it becomes visible
MainUI.Show();
timer = new CountDownTimer(seconds);
SubscribeToTickListener(timer);
TickUpdate(seconds);
}
internal void TickUpdate(string seconds)
{
MainUI.lblTimer.Text = ("" + Convert.ToInt32(seconds) / 60).PadLeft(2, '0') + "m:" + ("" + Convert.ToInt32(seconds) % 60).PadLeft(2, '0') + "s";
}
internal void TickUpdate(int seconds)
{
MainUI.lblTimer.Text = ("" + seconds / 60).PadLeft(2, '0') + "m:" + ("" + seconds % 60).PadLeft(2, '0') + "s";
if (seconds <= 10)
{
//ss.Speak(seconds.ToString());
}
else
{
//ss.Speak((seconds / 60).ToString() + " minute warning");
}
}
internal void StartTimer()
{
timer.StartTimer();
}
internal void ResetTimer()
{
timer.ResetTimer();
}
internal void StopTimer()
{
timer.StopTimer();
}
internal void SetTimer(int seconds)
{
timer.SetTimer(seconds);
}
public void SubscribeToTickListener(CountDownTimer cdt)
{
cdt.Tick += new CountDownTimer.TickHandler(TickMsgRecieved);
}
public void TickMsgRecieved(CountDownTimer cdt, EventArgs e, int seconds)
{
TickUpdate(seconds);
TickUpdate(seconds.ToString());
}
}
public class CountDownTimerTests
{
private CountDownTimer t = new CountDownTimer(300);
[TestMethod()]
public void CountDownTimerTest()
{
CountDownTimer t = new CountDownTimer(300);
}
[TestMethod()]
public void StartTimerTest()
{
//CountDownTimer t = new CountDownTimer(300);
t.StartTimer();
Boolean expected = t.isEnabled();
Boolean actual = true;
Assert.AreEqual(expected, actual);
}
[TestMethod()]
public void StopTimerTest()
{
//CountDownTimer t = new CountDownTimer(300);
t.StartTimer();
t.StopTimer();
Boolean expected = t.isEnabled();
Boolean actual = false;
Assert.AreEqual(expected, actual);
}
[TestMethod()]
public void ResetTimerTest()
{
int expected = t.getSeconds();
t.ResetTimer();
int actual = t.getSeconds();
Assert.AreEqual(expected, actual);
}
[TestMethod()]
public void SetTimerTest()
{
int expected = t.getSeconds();
t.SetTimer(120);
int actual = t.getSeconds();
Assert.AreEqual(expected, actual);
}
}
In this case you can probably use a mock implementation of the event. I would add the following mock event to your test class to simulate a consumer of the CountDownTimer class.
[TestInitialize]
public void TestSetup()
{
t.Tick += new CountDownTimer.TickHandler(MockTickEvent);
}
[TestCleanup]
public void TestCleanup()
{
t.Tick -= MockTickEvent;
}
void MockTickEvent(CountDownTimer m, EventArgs e, int seconds)
{
///you may need to add further test code here to fully cover your code
return;
}

Timer act crazy, Resets in different times not as defined

I have this class
public class ResetClock
{
public delegate void ResetFunc();
private ResetFunc m_ResetFunc;
private event ResetFunc Reseted;
private Timer m_Timer;
public ResetClock(int second)
{
double r = second * 1000;
m_Timer = new Timer(r);
m_Timer.AutoReset = false;
m_Timer.Elapsed += new ElapsedEventHandler(onTimerTick);
Reset();
}
public void SetResetMethod(ResetFunc method)
{
m_ResetFunc = method;
}
public void Terminate()
{
m_Timer.Stop();
m_Timer.Dispose();
m_Timer = null;
}
private void onTimerTick(object sender, ElapsedEventArgs e)
{
if (m_ResetFunc == null)
{
if (Reseted != null) Reseted();
}
else
{
m_ResetFunc();
}
Reset();
}
#region Public
public void Reset()
{
m_Timer.Reset();
}
#endregion
}
internal static class TimerEx{
public static void Reset(this Timer timer){
timer.Stop();
timer.Start();
}
}
My application is showing the reset page when this class reaches the seconds defined in the contractor. when a Reset() method calls, the Timer should reset the it self and begin the timer from 0.
for some reason after the application is running few days the reset event is firing after few seconds and not the number of seconds that i defined in the first application initialization
does anyone have any idea....??? I braking my head through the wall to find the answer..

Categories

Resources