I'd like to add "IDLE-like functionality" to C# WinForms application, but I don't quite have an idea how to do that and couldn't find anything useful with Google.
So basically I want interactive command line interface, where user could enter some Python code and execute it (not just expressions, should be possible to define new functions).
So, where to start? Are there any good tutorials or samples available?
If my memory serves me correctly there's a chapter on embedding Python in the book Python in a Nutshell. Perhaps you can find some useful information there, but since the book is not Windows specific, you may have to adapt it yourself.
I would setyp my WinForm like this: add 2 textboxes.
1: for output. Set the multiline property of the first to true, and make it read only.
2: for input. Use KeyUp Or KeyPress Event for e.g. the return key and use the text to do what you want: add command to output textbox, launch code against the engine and capture output of interpreter
This link (http://groups.google.com/group/ironpy/browse_thread/thread/5e61a944c7c94d4b/0cbf29ec0f5fbb64?pli=1) might give some answers about launching commands agains a python engine.
IronRuby comes with a command line interpreter. Doesn't IronPython also have one? If so, the source code would be a good start :)
Oh, and if it doesn't, be sure to look at the IronRuby interpreter, because both languages are based on the DLR and are therefore similar enough to learn from both.
Thru IronPython mailing list I found IronTextBox2, which is good example how things are done. It needs a little tweaking, to get it running, but otherwise is good solution.
Here go my most generic solution:
Point cursorPoint;
int minutesIdle=0;
private bool isIdle(int minutes)
{
return minutesIdle >= minutes;
}
private void idleTimer_Tick(object sender, EventArgs e)
{
if (Cursor.Position != cursorPoint)
{
// The mouse moved since last check
minutesIdle = 0;
}
else
{
// Mouse still stoped
minutesIdle++;
}
// Save current position
cursorPoint = Cursor.Position;
}
You can setup a timer running on 60000 interval. By this way you will just know how many minutes the user don't move the mice. You can also call "isIdle" on the Tick event itself to check on each interval.
Related
I have a plugin running inside Maya that needs to perform an 'eye dropper' test against objects in the scene. My Plugin is running as a hosted WPF control, so I have a C# button event callback that wants to operate in a modal fashion until the hit is performed or escape is pressed. This was really easy to do in 3D Studio Max, but I cannot find out how to do this in Maya.
Any advice?
I do miss that in 3dsMax, but as far as I know, no, there's no built-in functionality to do that.
Most tools in Maya work already having a selection before execution so then the tool can use cmds.ls(sl=True) to capture the selection and preform your validation.
What you can do is mimic an object picker by using a selection callback. There's cmds.scriptJob, but it's more efficient to use OpenMaya's callbacks. Here's an example that uses a class to store the callback's id and auto-manages it:
import maya.cmds as cmds
import maya.OpenMaya as OpenMaya
class ObjectPicker():
_id = None # Store callback's id here.
def __init__(self):
# When this class is created, add the callback.
OpenMaya.MGlobal.displayWarning("Please pick an object")
ObjectPicker.add_callback()
#staticmethod
def on_selection_changed(*args):
# This gets triggered from the callback when the user changes the selection.
# Auto-remove the callaback afterwards.
print "Selection:", cmds.ls(sl=True)
ObjectPicker.remove_callback()
#staticmethod
def add_callback():
# First remove any existing callback, then store the id in this class.
ObjectPicker.remove_callback()
ObjectPicker._id = OpenMaya.MEventMessage.addEventCallback("SelectionChanged", ObjectPicker.on_selection_changed)
#staticmethod
def remove_callback():
# Remove the callback so it stops triggering the function.
if ObjectPicker._id is not None:
OpenMaya.MEventMessage.removeCallback(ObjectPicker._id)
ObjectPicker._id = None
# After calling this, pick a new object then it will print it in the Script Editor.
picker = ObjectPicker()
After creating an new instance of the class with picker = ObjectPicker(), a warning will pop-up to the user to pick an object. After the selection changes, it triggers the callback which prints the selection to the Script Editor then removes its own callback.
I think this might work, but Maya isn't 3dsMax, and at the end of the day it might be best to not force one software to work like another. So I'd consider to just stick with what everyone is already used to, and that is to work with the user's current selection.
Edit:
Sorry just noticed c++ tag, but the same concept should apply.
Edit #2:
I just learned about the command cmds.scriptCtx, so a picker does exist! I think it's an older command as it seems to only support MEL and the implementation doesn't feel that great. If you want to learn more then check out my answer to another question.
There is the whole super simple C# console app here:
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
int left = 0;
Console.SetCursorPosition(++left, 0);
while (true)
{
ConsoleKeyInfo stisknutaKlavesa = Console.ReadKey(true);
if (stisknutaKlavesa.Key == ConsoleKey.RightArrow)
{
Console.SetCursorPosition(++left, 0);
Console.Write("#");
}
}
}
}
}
Description: When I press RIGHT KEY (and hold it!!) it quickly writes one hash, then there is a pause, and then it fluently keeps writting another hashes further.
How can I get rid of that pause? I have been dealing with identical problem in one of my winform app, but for simplicity I posted it in this console application here.
I have found some answers about this topic but all of them were about javascript (jquery) and i did not understand how to apply it on this my c# project.
And i do not want to resolve it in asynchronous way either. Is there such a solution, please?
This comes from the way that the windows console (and most other text-based inputs in Windows and other environments) behaves. If you put your cursor on any text input (like your browser's address bar, for instance), and press and hold an arrow key, you will see it move once, pause, and then start moving repeatedly with a much shorter pause.
In effect, your console's ReadKey registers keypresses based on some predefined behaviors of the operating system.
If you want to be able to detect and respond to someone holding a key down, you'll need to use a medium that gives you more low-level access to events like keydown and keyup. Something like Windows Forms, WPF, Unity... pretty much anything that's not Console.
Furthermore, if you want to respond to those key-down and key-up events using timing that's different from how the system treats those events, you'll have to create your own timing mechanism, and only use those events to help you know when things have changed. Examples of this can be found here and here.
If you're trying to make something akin to a video game, you might consider looking into libraries that are specifically designed for these use cases, like Unity3D.
I have been learning C# using the book "Programming in the Key of C#...", this book has been very good in helping me understand the language but only deals with Console programs. I am ready to move on to developing versions of my past coding projects as Windows form applications but one program in particular is causing me a lot of frustration. I developed a simple movie trivia program utilizing arrays to hold the questions, answer choices, and the correct answer. It worked by displaying on the console the questions, the possible answers and waited for the user to provide a response (basically A,B,C or D) by using Console.Readline() to assign the response.
Now I want to be able to have the user enter the answer by selecting 1 of 4 buttons (A through D). Based on my old code, I am unsure how I get the program to wait for the user to click one of the buttons. I assume i need to change the nature of the loops but I just cant figure out how. Any help would be much appreciated.
Here is a snippet of my Console code:
while (iAsked < 5)
{
iLocation = rand.Next(0, astrQuestions.GetLength(0));
if (list.Contains(iLocation))
rand.Next(0, astrQuestions.GetLength(0));
else
{
iAsked++;
list.Add(iLocation);
Console.WriteLine("Question {0}", iAsked);
Console.WriteLine("------------");
Console.WriteLine(astrQuestions[(iLocation)]);
Console.WriteLine(astrChoices[(iLocation)]);
Console.Write("Answer:");
iResponse = Console.ReadLine();
if (iResponse == astrAnswers[(iLocation)])
{
Console.WriteLine("Correct\n");
iPoints += 5;
iCorrect++;
}
else
{
Console.WriteLine("Incorrect\n");
}
}
Moving from a prompting-centric environment like a console program to an event-driven environment like Winforms, yes…that definitely will require at least some change in "the nature of the loops". :)
That said, the latest version of C# offers an async/await-based approach that can minimize some of the culture-shock that might come from moving from console to GUI. Writing and using async method is itself non-trivial, but IMHO the simpler scenarios are not too hard to understand. More importantly, because it allows you to structure the code in a more directly-imperative way, similar to that which would be used in a console program, it's very much worth learning this along with Winforms generally.
In your particular scenario, you have two separate things you'll need to deal with: prompting the user, and receiving the user's input.
Because of the way an event-driven system works, you need to separate these tasks. But .NET has a class, TaskCompletionSource, which we can use to keep the two glued together, even though they wind up in different places.
First, what happens when the user starts the process? Presumably, you'll have a form, where on that form is a button (or possible a menu item) which when clicked/selected, starts the whole thing. That might look something like this:
private TaskCompletionSource<bool> _completionSource;
private async void button1_Click(object sender, EventArgs e)
{
int[] questionIndexes = ShuffleQuestions();
for (int iAsked = 0; iAsked < 5; iAsked++)
{
textBoxQuestionNumber.Text = string.Format("Question {0}", iAsked);
textBoxQuestion.Text = astrQuestions[questionIndexes[iAsked]];
textBoxChoices.Text = astrChoices[questionIndexes[iAsked]];
_completionSource =
new TaskCompletionSource<bool>(astrAnswers[questionIndexes[iAsked]]);
button2.Enabled = true;
bool result = await _completionSource.Task;
MessageBox.Show(result ? "Correct" : "Incorrect");
if (result)
{
iPoints += 5;
iCorrect++;
}
button2.Enabled = false;
_completionSource = null;
}
}
private void button2_Click(object sender, EventArgs e)
{
if (_completionSource != null)
{
_completionSource.SetResult(
textBoxUserAnswer.Text == (string)_completionsSource.Task.AsyncState);
}
}
(I have changed your question-selection logic above to something more efficient, by assuming that you have a ShuffleQuestions() method. See Is using Random and OrderBy a good shuffle algorithm? for details on how to implement that).
What the above code does is, in response to the user clicking the button1 button (which presumably has text like "Start" or something), executes a loop that is very similar to what you had in your console program. The two main differences are:
Where in your console program, you use Console.WriteLine() to display text to the user, here I have shown the use of TextBox controls in your form which are used to display the same text.
What in your console program, you use Console.ReadLine() to receive input from the user, this loop creates a TaskCompletionSource object for a completely different method to use. That method, which is executed with your button2 button (which presumably has text like "Check Answer" or something) will read the text entered in a text box by the user (here, I've given it the name textBoxUserAnswer), compare it to the correct answer for the question (which has been provided to this method by the other method via the AsyncState property of the Task created by the TaskCompletionSource object I created), and set the Task's result to true or false, depending on whether the user got the answer correct or not.
The tricky part above is that "under the hood", that first method actually returns as soon as it is done filling in the text for the first question and reaches the await statement in the loop. The compiler rewrites the entire method to facilitate this.
When button2 is pushed, and sets the result of the Task, the framework then knows to resume executing the first method where it left off at the await statement, continuing your loop.
This sequence continues until the user has answered all of the question.
Some final notes about the UI:
I have used TextBox's everywhere for user input and output. Of course, there are other ways to display text. Also, the default state for a TextBox is a single-line, read/write text. But for displaying to the user, you may find that setting the ReadOnly property of the TextBox to true is better (i.e. to prevent the user from accidentally changing the text), and/or that you prefer setting the Multiline property to true (i.e. so that more than one line of text is displayed).
The above also assumes that the initial state for the button2 button's Enabled property is false. I.e. that button can't be clicked until the first method above explicitly enables the button at the appropriate time.
I come from a PHP background and have used Wordpress quite a lot, I love how their plugin architecture works and the ability to hook events to event names. One of the best parts I like about it is being able to *add_filter()* to any database value just before it gets shown to the end user. My question is multi-part on how to replicate the whole plugin architecture in a C#.NET environment?
Part 1:
To create plug-ins I have researched the MEF framework would probably be the best (Managed Extensibility Framework -http://mef.codeplex.com/). This is designed specifically to take the grunt work out by giving you the ability to monitor directories for new plug-ins, tracking dependencies and other normal things. MEF ships with .NET 3.5+
Part 2
Hooking events? I can't seem to find much information about replicating a global channel based event system. From what I have upto yet I need a publish/subscribe pattern (which isn't that hard to make as you just create some concrete objects and give them events). The hard part is giving each event a 'channel' name and for all the events in the whole system to be part of a global collection (Mediator pattern).
To replicate: (http://codex.wordpress.org/Function_Reference/add_filter)
Example 1
// Add's my button to the end of the content
add_filter('the_content', 'my_plugin_button');
function my_plugin_button( $content ) {
// Add's my button to the end of the content
return $content . "<a href='#'>My button</a>";
}
OR
Example 2
// Add a new admin menu item by hooking in
add_action('admin_menu', 'my_plugin_menu');
function my_plugin_menu() {
add_options_page('My Plugin Options', 'My Plugin', 'manage_options', 'my-unique-identifier', 'my_plugin_options');
}
I hope your all with me upto yet? I have managed to replicate the functionality I need in Javascript and even jQuery has their .on() event function... same thing but channel or list based...
My 2 examples:
http://jsfiddle.net/AaronLayton/U3ucS/53/
http://jsfiddle.net/AaronLayton/eyNre/33/
Can anyone point me in the correct direction or is this the totaly wrong approach for c#?
I think NServiceBus can help you a lot with these issues. Udi Dahan which is the author of NServiceBus has also written a lot of articles about Domain Event pattern, which is a publish/subscribe mechanism.
Know it's been a long time since you posted this and you probably built something already. However I have been thinking about something like this myself. There are 2 options - really forget WordPress and try and build something much cleaner - it's a mess at the bottom of WordPress' code :D
Or this:
function the_content()
{
var result = get_the_content();
// do other stuff...if you want to.
execute_filters(ref result);
execute_actions(ref result);
return result;
}
function execute_filters(ref string result, string action_name)
{
var filters = get_pre_filters(action_name);
filters.ForEach(filter =>
{
/// somehow call the method name in filter. PHP is generally global. C# namespaced,
/// so you would need to think about that.
}
}
function execute_actions(ref string result, string action_name)
{
/// and so on....
}
When building something to mimic WordPress, you need to remember many of the issues of WordPress' plugin architecture (in my personal opinion)... It seems to want to run every plugin near enough on every page even if that page has nothing to do with that plugin. I onced installed a plugin that added 60 database queries to each page call, and it wasn't used.
Try and think smart about it when you are building it. Try and add a way to only have the plugins that are going to get used on the page/post of your new setup to be run e.g. in your database have a "Plugins" field on the post/page object with a list of plugins allowed to run on that page. That way you won't need to check all the plugins each time to see if it wants to run.
Anyways. Hope you got something working.
I am trying to automate testing of a winform application. I am running it in the same process as the test code, so it is fairly easy to find the .Net controls and simulate user action on them. I got however stuck a bit with a message box (created using the standard MessageBox.Show method). How can I get hold of it and simulate that a button is pressed?
I'd advise treating the underlying disease rather than the symptom.
Take a few minutes to read these
the Humble Dialog box by Michael Feathers
User Interrogator by Tim Haughton
In short, use an interface to separate out all modal dialog pop-ups - which are a pain in the neck for UI test automation. You can then substitute a mock implementation of the interface that does nothing or returns predetermined test values. The real implementation of course pops up the actual dialog modally... something like this (from the 2nd link)
public class UserInterrogator : IUserInterrogator
{
private Form owner;
public UserInterrogator(Form owner)
{ this.owner = owner; }
public Font GetFontFromUser() // member of the IUserInterrogator interface
{
FontDialog fd = new FontDialog();
fd.ShowDialog( owner );
return fd.Font;
}
}
The easier approach is of course to write some code that finds the dialog and closes/kills it. I've seen some people have some success with Win32 APIs and NUnitForms ...
codeplex.com/white - Free
testautomationfx.com - Commercial but very good
You probably will have to use WinAPI calls (FindWindowEx, ect) and send a messages of LMB down and up to a button handle.
If you know the caption (and it is unique) you can loop through Application.OpenForms to find it.
One of the best free tools is AutoHotKey.
You can use autoit script system.
But i am suggest to separate the GUI and implementation, because basic principle of unit testing is "unit", where unit is class that separated from other classes or real world.
This principle give you good class design and help to avoid software eruption and lot of other good stuff..