I am trying to use a gamepad to control an application. It's not a game, just a plain application using Windows Forms. So it doesn't have a game loop/update process or anything like that. I wouldn't like to use XNA because I think it's a huge overload just to capture a button press.
I am experimenting with both SlimDX and SharpDX. As I understand, they are just wrappers for DirectX, right?
Looking at the documentation, it seems like there is no event for a button press. So I have been looking for an alternative. I have tried adding a timer (from the System.Windows.Forms.Timer class), and reading the state of the gamepad like this:
private void timer_tick(object sender, EventArgs e)
{
State s = controller.GetState();
stateLabel.Text = s.Gamepad.Buttons == GamepadButtonFlags.A ? "A" : "";
}
With a small enough interval between timer ticks (I'm using 10ms), I can see whether the button is pressed or not. However, I don't want to handle the button press multiple times should the button be held down - I need to make sure it has been released before handling the button press again. Between two ticks of the timer, I don't know if a button was pressed twice or if it was just being held down.
I thought about using the packet number in the controller state, but it will change at the slightest touch on an analog stick or shoulder trigger.
Help?
From what I can gather after reading you question over a few times is that you are wanting to log a button press only 1 time until it is released. You probably should use the packet number technique to keep track of any changes to the other input.
To get a single input from the button being held down as opposed to getting continuous input (1 as opposed to 11111111...etc) create an old state an a current state. Then compare the old state with the new state.
Something like this:
class Input
{
State old;
void GetInput()
{
State new = controller.GetState();
if (this.old.GamePad.Buttons == GamepadButtonFlags.A && new.GamePad.Buttons == GamepadButtonFlags.A)
{
// Do stuff that will be called only once.
}
this.old = new;
}
}
Related
First off I would like to say that I am kinda new to visual studio C# (2 months in) & I've studied other languages but I know the fundimentals & the project is somewhat done, its just this one feature I cant seem to get the hang of.
So I am trying to connect a trackBar to my WinForm application which is a SoundBoard.
It is not driven by Windows Media Player it is simply just some resources (Audio Files)
It is a really boring project its really nothing special but I really cant seem to get the code to work.
(Will provide the .cs files if necessary)
What I am trying to accomplish is that I want to make a trackBar that connects to the winForm app & lets the user control the volume of the WinForm itself.
I know I need to set the min and max values according to my needs at the beginning, like in the Form_Load event.
E.g. the volume control uses percentage 0 - 100%
Then I need to set min=0, max=100.
the thing is, I have no idea how to do it, I have never seen any code that makes any sence in this scenario.
Here is the code for the trackBar, or this is what I've gotten so far. I know its not much but I am really bad with trackBars.
(Sorry for my bad english, not my native tounge.)
private void trackBar1_Scroll(object sender, EventArgs e)
{
trackBar1.Minimum = 0;
trackBar1.Maximum = 100;
}
This is the code for the sounds being played with each button that is named differently.
System.Media.SoundPlayer player = new System.Media.SoundPlayer();
player.Stream = Properties.Resources.cow;
player.Play();
There is no sense in modifying the Minimum and Maximum values within an Scroll event. Just set these values to 0 and 100 in designer (Properties window).
Then, you will be able to use this event and control the volume through it:
private void trackBar1_Scroll(object sender, EventArgs e)
{
yourSoundPlayer.Volume = trackBar1.Value;
}
As you haven't told what you use for playing a sound, I have assumed the Volume property. However, it may be another in your case.
I am developing a Kinect game in C# where the user needs to click 2 buttons at the same time by hovering over one button with each hand.
However, with my current code, when the user hovers with one hand over a button, the other buttons get disabled and the other hand can only click when the first hand stops hovering over a button.
To solve this, I'm thinking of queuing the second click while the first click is being processed. To do this, I have used the following code based on this link
private Queue<System.Windows.Controls.Button> Button_Queue = new Queue<System.Windows.Controls.Button>();
private bool isProcessing = false;
private void Button_Click((object sender, RoutedEventArgs e){
if(isProcessing){
Button_Queue.Enqueue(this);
}
else
{
isProcessing = true;
// code here
isProcessing = false;
while(Button_Queue.Count > 0){
Button_Queue.Dequeue().PerformClick();
}
}
However, the Button_Queue.Enqueue(this) line shows the error
"The best overloaded method match for Queue.Enqueue has invalid
arguments."
I'm guessing this is because the button click event cannot be queued in a queue declared with the type Button.
Do you have any suggestions for how to create this queue of button click events or another way to handle multiple clicks from the user?
You don't need to queue the event. If isProcessing is true, then the other button was already clicked, so you can handle the event for both button clicks from that point on.
You could measure the time between the two clicks, to work out if it validates as a "two buttons clicked at the same time" event.
Have you considered a more low-level approach? The first thing that came to mind was to create two hot areas instead of buttons and monitor whether the user's hands are inside those areas at the same time.
It is unclear to me why another button is disabled when you hand is hovering over another object. Without seeing the code, I would say that you are doing something that would cause that -- and there is no reason to.
Additionally, you should be using interaction concepts centered around a gesture system and not something that is written for a mouse/keyboard input. Using regular UI objects and interacting with them in ways that parallel traditional inputs will only serve to confuse the users.
Have a look at the following two examples, which use a "hover-to-click" and a "press-to-click" interaction
Basic Interaction, for SDK 1.6
Control Basics, for SDK 1.7 (in Kinect for Windows Developer Toolkit)
In both cases, you are using a hit test on custom controls to handle events. Here is an example of a hit test function I use in one of my apps:
private void HitTestHand(HandPosition hand)
{
// quick fix to null pointer exception on exit.
if (Application.Current.MainWindow == null)
return;
Point pt = new Point(hand.X, hand.Y);
IInputElement input = Application.Current.MainWindow.InputHitTest(pt);
if (hand.CurrentElement != input)
{
var inputObject = input as DependencyObject;
var currentObject = hand.CurrentElement as DependencyObject;
// If the new input is a child of the current element then don't fire the leave event.
// It will be fired later when the current input moves to the parent of the current element.
if (hand.CurrentElement != null && Utility.IsElementChild(currentObject, inputObject) == false)
{
// Raise the HandLeaveEvent on the CurrentElement, which at this point is the previous element the hand was over.
hand.CurrentElement.RaiseEvent(new HandInputEventArgs(HoverDwellButton.HandLeaveEvent, hand.CurrentElement, hand));
}
// If the current element is the parent of the new input element then don't
// raise the entered event as it has already been fired.
if (input != null && Utility.IsElementChild(inputObject, currentObject) == false)
{
input.RaiseEvent(new HandInputEventArgs(HoverDwellButton.HandEnterEvent, input, hand));
}
hand.CurrentElement = input;
}
else if (hand.CurrentElement != null)
{
hand.CurrentElement.RaiseEvent(new HandInputEventArgs(HoverDwellButton.HandMoveEvent, hand.CurrentElement, hand));
}
}
Notice that an event is being fired on the element below the hand cursor. Examples of these elements can be found in the two links above (the HoverDwellButton is what I use with the above code sample).
Two events on two different elements, or the same element, can fire at any time with this. You can easily keep track of which user is over which button, if that button is in the process of being pressed, or if it has been pressed.
The key to all this is not using a UI paradigm that isn't designed for gesture systems! Don't try to shoehorn the keyboard/mouse event structure into a gesture based system -- it will only cause you more pain in the long run and cause your users confusion.
I want to make a windows form application that I can open multiple times.
When I click the "GO" button on the first form, I want the mouse to perform a series of clicks within the form (given by specific coordinates), while I still have control over the cursor using my hand-held mouse, so essentially there are 2 mice.
If I click the "GO" button on all forms, I want all the mice to perform a series of clicks within the corresponding form (all running in unison, not effecting one another), while I still have control over the hand-held mouse to do what I want I.E. browse the web.
Is this possible to do? IF so where would I start?
You can use PInvoke and call the SendInput API.
http://www.pinvoke.net/default.aspx/user32.sendinput
To the best of my knowledge it is impossible to have two mice on one windows system, if you simulate a click somewhere it normally moves the mouse to that location.
You can try the lib Wolfgang suggested or you can use the code from this question
As for it running multiple times you could just load up multiple threads all running the same code, like this:
static void Main(string[] args)
{
Thread[] threads = new Thread[5]; // replace 5 with how many times you want to run it.
for(int i = 0; i < threads.Length;i++)
{
threads[i] = new Thread(new ThreadStart(MyCode));
threads[i].Start();
}
}
static void MyCode()
{
//put code here
}
Did some searches here & on the 'net and haven't found a good answer yet. What I'm trying to do is call a button twice within the same class in C#.
Here's my scenario -
I have a form with a button that says "Go". When I click it the 1st time, it runs through some 'for' loops (non-stop) to display a color range. At the same time I set the button1.Text properties to "Stop". I would like to be able to click the button a 2nd time and when that happens I would like the program to stop. Basically a stop-and-go button. I know how to do it with 2 button events, but would like to utilize 1 button.
Right now the only way to end the program is the X button on the form.
I've tried different things and haven't had much luck so far so wanted to ask the gurus here how to do it.
BTW, this is a modification of a Head First Labs C# book exercise.
Thanks!
~Allen
You would need to use Multithreading (launch the process intensive code asynchronously in a separate thread), for instance, using the BackgroundWorker object in .NET 2+. This would be necessary because your UI will not respond to the user's click until the loop running in the Start method is completed. It is quite irrelevant if you use the same button or another one to toggle the process, because the processor is busy processing the loop.
The BackgroundWorker has a property called WorkerSupportsCancellation which needs to be true in this scenario. When the user clicks Stop you would invoke the CancelAsync method of the BackgroundWorker.
See MSDN for a good example. Also DreamInCode has a good tutorial which seems quite similar to your requirement.
Why not create two buttons, hide one when the other is visible? That should be a lot of easier to handle.
Or you can add a bool field to indicate which operation branch to execute.
One simple solution would be to add a boolean member to your form that is, e.g., true when the button says "Go" and false when the button says "Stop".
Then, in your button's event handler, check that boolean value. If the value is true, then start your operation and set the value to false when you change the button's text to say "stop". Vice-versa for the other case. :)
There are other techniques that I might prefer if this were production code, perhaps including considering the design of the form more carefully, but as this is clearly a learning exercise I believe that a simple boolean flag indicating the current state of the form is just what you're looking for.
Note that I would strongly discourage you from checking the value of the button text to determine what state the object is in. Whenever possible, as a general rule of good design, you want your visual state to be "decoupled" from your underlying object's state. That is to say, your visual widgets can depend on your underlying objects, but your underlying objects should not depend on your visual widgets. If you tested the text of the button, your underlying logic would depend on your visual state and that would violate this general rule.
If your problem is related to the fact that you can't cancel the operation while it's being performed, you'll want to look into using a BackgroundWorker to perform your long-running activity.
Another option would be to check the current text on your button to determine what to do:
void btnStartStop_Click(Object sender, EventArgs e)
{
if (btnStartStop.Text == "Go")
{
btnStartStop.Text = "Stop";
// Go code here
}
else
{
btnStartStop.Text = "Go";
// Stop code here
}
}
Are you getting your second button click event? Put a breakpoint in your click handler and run your code. When you click the second time, do you ever hit your breakpoint?
If your loop is running continuously, and it is in your button click handler, then your loop is running in the UI thread. You probably don't get to "see" the second button click until after the loop is completed. In addition to the branch code that you see above, try either inserting a DoEvents in your loop processing (this is a place where your loop will temporarly give up control so that messages can be processed). Or, (better) have a look at the backgroundworker class -- do most of your processing in a different thread, so that you UI can remain responsive to button clicks.
Cerebrus is right about using the Background Worker thread. However if you are doing a WPF app then it won't be able to update the UI directly. To get around this you can call Dispatcher.BeginInvoke on the main control/window.
Given code like:
Private Delegate Sub UpdateUIDelegate(<arguments>)
Private Sub CallUpdateUI(<arguments>)
control.Dispatcher.BeginInvoke(Windows.Threading.DispatcherPriority.Background, New UpdateUIDelegate(AddressOf UpdateUI), <arguments>)
End Sub
Private Sub UpdateUI(<arguments>)
'update the UI
End Sub
You can call CallUpdateUI from the Background Worker thread and it will get the main thread to perform UpdateUI.
You could set the Tag property on the button to a boolean indicating whether the next action should be "Stop" or "Go", and reset it each time you click the button. It's an Object property, though, so you'll have to cast it to bool when you read it.
In the application I am working with, if the user changes the value in a cell that is say positive to negative and the value is supposed to be positive at all times, the application forces the positive value. Right now, when this happens there is no alert shown to the user.
I would like to show a little unobtrusive alert, like the one that shows up when a new mail arrives in outlook, or something similar, so that the user can be alerted that the application did something on her behalf.
I tried using the NotifyIcon class to do this. But the problem with that class seems to be that the timeout on it doesn't work as expected. I want to show this alert for not more than 2s and the BallonTipText lasts for longer than 10s.
Is there a .NET class for this purpose?
If not, is there an alternate way to do something like this?
Using a notification icon for this case seems wrong to me. The user's attention is, when entering something into a cell, on the cell. If you display the notification on the lower right of the screen the user is very likely to miss it, or worse, it disrupts his work flow.
You might instead consider adding a balloon tip to the cell the user is editing. Kinda like the balloon tip Windows Explorer is showing on Vista and Windows 7 on renaming a file when you try entering a character that is disallowed in file names:
I have had this problem in the past. I gather that the timeout problem is because the operating system fixes a minimum value of 10 seconds and a maximum value of 30 seconds (or something like that).Edit Oh and this doesn't include time that a user is idle.Edit
I have used the following code in the past to get around this.
Just to clarify
Declare a public variable, say called ballonTipActive with a value of 0.
Insert a timer control disabled with 100ms delay and create an event from BalloonTipShown from the notifyicon control.
Then
private void ptNotifyIcon_BalloonTipShown(object sender, EventArgs e)
{
timer1.Enabled = true;
balloonTipActive = 0;
}
private void timer1_Tick(object sender, EventArgs e)
{
balloonTipActive++;
if (balloonTipActive == 40)
{
ptNotifyIcon.Visible = false;
ptNotifyIcon.Visible = true;
balloonTipActive = 0;
timer1.Enabled = false;
}
}
Setting the visible property to false then true gets rid of the balloon.