views:

58

answers:

2

In Flash 10 there are methods that require that they are triggered from user-initiated actions like button click, keyboard up/down keys, etc.

Is it possible to implement this behaviour in .NET? For example, if we have this subroutine:

void SomeMethod() {
   // Here some stuff
}

how to check inside it whether the method was called from a mouse click event handler?

Also we can think of this methods like the protected functions in World of Warcraft, if anyone knows what I mean.

EDIT: Looks like this behaviour is implemented in Silverlight — we can popup file dialogs (open, save) ONLY by mouse click or other user-initiated action, otherwise a SecurityException will be thrown. I want to achieve this bevaviour but in my case it’s not a file dialog but our own methods.

+1  A: 

Why not just provide it as a parameter?

void SomeMethod(bool userInitiated) {
   // Here some stuff
}

Given that you're already calling it, sometimes from an event handler and sometimes not, you already have that information.

EDIT: Another approach is to have a thread-static field which you set on entry to an event-handler and then reset on exit (in a finally block). Any code which wants to test whether they're "responding to a user action" can then test that field.

If that's not good enough, then I suspect the answer is simply "no".

EDIT: You can get at the call stack (see the StackTrace class) but that's relatively slow and can miss out stack frames due to inlining. There's also Code Access Security which may just about help you - but I doubt it.

Jon Skeet
you didn't understand a question. Because of security. In Flash 10 we can't call System.setClipboard() from code that was not triggered by user, for example by mouse click. This ensures that user will know about what will happen now, and user will know what no thing will happen if user don't want it.
myfirstandlastquestion
@myfirstandlastquestion: The question still isn't terribly clear - you haven't provided much context for what this code is, or what you're trying to achieve. I've edited my answer, but without more information it's unlikely to be terribly useful.
Jon Skeet
and can we check call stack?how this checks occurs in Silverlight when we need to open file dialogs?
myfirstandlastquestion
@Jon Skeet, sorry, maybe the question really still isn't terribly clear) but let's try to find solution together, i will thank for help any way
myfirstandlastquestion
@Jon Skeet, thanks, i will read about it. Below Timwi described right what i want to archieve. If there are thoughts, you will be welcome!
myfirstandlastquestion
@myfirstandlastquestion: That's exactly what I described in my middle paragraph, isn't it?
Jon Skeet
A: 

It seems that you are writing some sort of plugin API. You want to provide a method that does something the user might not want, e.g. changes the clipboard contents, and you want to ensure that your plugins can call that method only in response to a user action.

The only way I can think of to do this is that the API needs to be continually aware of whether it is currently processing a user-initiated action or not. Presumably there will be some code in your program that calls the plugin-provided code, e.g.

if (plugin.HasHandlerForMouseClick)
    plugin.HandleMouseClick();

At this point you will need to remember that this is a user-initiated action. Once the method returns, that’s the end of the user-initiated action:

if (plugin.HasHandlerForMouseClick)
{
    _userInitiated = true;
    try
    {
        plugin.HandleMouseClick();
    }
    finally
    {
        _userInitiated = false;
    }
}

Then, in your “unsafe” method, e.g. the one to set the clipboard, you will have to check this flag:

public void SetClipboard(object newValue)
{
    if (!_userInitiated)
        return;    // or throw AccessDeniedException?

    // set clipboard here
}

As hinted by Jon, the field should be declared thread-static. This means that there is a separate copy of the field for each thread:

[ThreadStatic]
private static bool _userInitiated = false;
Timwi
yeap, you noticed about what i want to archieve absolutely right. But now i don't understand what is HasHandlerForMouseClick and HandleMouseClick, how to link this and plugin-user? Can you explain please? maybe some light examples
myfirstandlastquestion
@myfirstandlastquestion: I have no idea what the methods in your plugin API are called, so I had to make something up.
Timwi