views:

23

answers:

1

I want to write a custom control (a text editor) for Windows Forms, which should include the following functionality:

  • Gets the keyboard focus, when you click on it with the mouse
  • Sees all keyboard input (including cursor keys), when it has the focus,
  • Can run in a semi-trusted environment, with UIPermissionWindow.SafeTopLevelWindows (i.e. it shouldn't require UIPermissionWindow.AllWindows)

Is there any example of doing this?

Some of the methods which I might want to use, like Control.Focus() and Control.InInputKey(), require UIPermissionWindow.AllWindows.

Is there any other way to get/implement the functionality, without using these methods?

The built-in TextBox control has this functionality (gets the focus and handles cursor keys).

+1  A: 
Public Class UserControl1
    Inherits TextBox

    Private Sub UserControl1_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.GotFocus

    End Sub

    Private Sub UserControl1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
        Debug.WriteLine("downed")
        Debug.WriteLine(e.KeyValue)
        Debug.WriteLine(e.KeyCode)

    End Sub

    Private Sub UserControl1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
        Debug.WriteLine("pressed")
        Debug.WriteLine(e.KeyChar)
    End Sub
End Class
vulkanino
The GotFocus event is fired when it gets the focus, but doesn't cause the focus. To get the focus on a mouse click, I might have wanted to invoke this.Focus() in the MouseDown event handler (but can't because Focus() requires UIPermissionWindow.AllWindows).
ChrisW
The KeyDown event handler doesn't get various keys, including the Return and Arrow keys, because they are 'preprocessed' unless IsInputKey retrns true (and overriding IsInputKey requires UIPermissionWindow.AllWindows).
ChrisW
Your event handlers work when you inherit from TextBox instead of inhering from Control; I guess that TextBox is doing the necessary Focus() and IsInputKey() internally. I don't know how to derive from TextBox though: because TextBox paints itself, and overriding OnPaint isn't enough to override/conceal TextBox's painting (I think TextBox is doing some unmanaged painting as well). I'd like to have/implement the same focus and arrow key behaviour as TextBox, but I don't see how. Note that TextBox is allowed to run even in a `UIPermissionWindow.SafeTopLevelWindows` environment.
ChrisW
why would you override OnPaint?
vulkanino
please try my code. if you want to override OnPaint then do: Sub New() InitializeComponent() SetStyle(ControlStyles.UserPaint, True) End Sub Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)'... End Sub
vulkanino
I want to override OnPaint because I'm developing a custom control, and I want to do my own painting: the control displays multiple lines, multiple fonts, rectangles, etc.
ChrisW
@vulkanino "please try my code" - It works, if the base.Text is an empty string (if the TextBox.Text contains text, then that text is painted even though I override OnPaint and don't call Base.OnPaint ... I think it's being called by unmanaged code). The problem (the only problem) I see now is that the base TextBox is painting its insertion caret (that blinking vertical line) whenever it has the focus.
ChrisW
Ok my plan is: (1) in a high-trust environment, derive from Control; (2) else in a low-trust environment, derive from TextBox, if there's a toolbar under which I can hide the caret; (3) else in a low-trust environment without a toolbar under which to hide the caret, derive from Control and have a hidden TextBox as a member (then I can at least get all the keystrokes from the hidden text box while the text box has the focus; although a mouse click on the control won't set the focus).
ChrisW
*You don't read Chris.*Call this method in your derived class constructor: SetStyle(ControlStyles.UserPaint, True)Your OnPaint will be called and you'll decide what to write in the control, with your own brushes and everything.
vulkanino
I *am* calling `SetStyle(ControlStyles.UserPaint, true)`. If I don't call it, then my OnPaint is never called at all. However even though I set `ControlStyles.UserPaint`, even though my `OnPaint` is called, even though I can paint any/everything I like, and even though my `OnPaint` does *not* invoke `base.OnPaint`, nevertheless the base TextBox is *still doing some painting of its own*: of any text which it contains, and its caret is being painted too. I guess that painting is being done by unmanaged code (perhaps a Win32 edit control), which I can't override/ignore in the subclass.
ChrisW