Cut, Copy and Paste?

G

Guest

Hi,

I've got a vb.net winforms app. Out of the box, I can use Ctrl X, C and V as
expected in controls like textboxes. I've got a menustrip, and if I click the
link "Add standard items" which adds Cut copy and paste commands, this
functionality no longer works. It seems now I need to implement handlers for
these functions. I tried to do so, but say the paste handler, I need to call
paste on a specific control and that isn't necessarily where the insertion
point is (could be a completely different control). Needless to say, this
functinoality works much better without these menu items. What's going on
here? Are users supposed to implement their own cut copy paste functions? If
so, how can I make them work regardless of which control I'm working in at
the time?

Thanks...

-Ben
 
M

MyndPhlyp

Ben R. said:
Hi,

I've got a vb.net winforms app. Out of the box, I can use Ctrl X, C and V as
expected in controls like textboxes. I've got a menustrip, and if I click the
link "Add standard items" which adds Cut copy and paste commands, this
functionality no longer works. It seems now I need to implement handlers for
these functions. I tried to do so, but say the paste handler, I need to call
paste on a specific control and that isn't necessarily where the insertion
point is (could be a completely different control). Needless to say, this
functinoality works much better without these menu items. What's going on
here? Are users supposed to implement their own cut copy paste functions? If
so, how can I make them work regardless of which control I'm working in at
the time?

I'm not sure I know what you mean by making "them work regardless of which
control I'm working in at the time."

The Paste operation is something you want to make universal to all forms and
all text-like objects on the forms. Normal operation is to insert the
contents of the Clipboard into whatever form and whatever object on the form
has focus at the point where the cursor is located (or the stuff that is
selected).

Determining the active form and object can be done from the parent using
Me.ActiveForm.ActiveObject.

The Clipboard.GetText (et al) will retrieve the contents of the Clipboard.

So from the parent you could do something as simple as
Me.ActiveForm.ActiveObject = Clipboard.GetText. If the Clipboard contains a
mixed bag of goods (text with embedded OLE objects, for example) you'll have
to work on a more involved solution.
 
G

Guest

Hi,

What is the solution that is employed by default when I highlight text and
press control + c and control + v? This works perfectly. Then, it stops
working once I add copy and paste menu items. What is the code that is
executed by default in the former scenario? Can I bring that to the scenario
where I have menu items for cut copy and paste?

Thanks...

-Ben
 
J

Jeffrey Tan[MSFT]

Hi Ben,

Thanks for your post!

Yes, I can reproduce this behavior. Let me clarify the internal work and
design to you:

1. The default Ctrl+C/V copy/paste behavior of TextBox is not implemented
by .Net, it is totally supported by underlying Win32 Edit control.(Note:
Net TextBox control is a wrapper around Win32 Edit control). If you open
Notepad, the editing rectangle in it is a big Edit control(you may use
Spy++ to verify this), you will find that the Edit control of notepad will
have Ctrl+C/V copy/paste function defaultly.

2. After you adding standard menustrip to the Form, this behavior is lost.
It is prohibited by ToolStripMenuItem.ShortcutKeys property. You will find
that the following code in Form1.Designer.vb file(note: in hidden text):
Me.CopyToolStripMenuItem.ShortcutKeys =
CType((System.Windows.Forms.Keys.Control Or System.Windows.Forms.Keys.C),
System.Windows.Forms.Keys)

By using this code, .Net winform will intercept all the Ctrl+C key
combination and translate it into CopyToolStripMenuItem.Click event. If you
are curious, below is the source code that intercepts the short cut key and
fires the Click event:

Protected Friend Overrides Function ProcessCmdKey(ByRef m As Message, ByVal
keyData As Keys) As Boolean
If ((Me.Enabled AndAlso (Me.ShortcutKeys = keyData)) AndAlso Not
Me.HasDropDownItems) Then
MyBase.FireEvent(ToolStripItemEventType.Click)
Return True
End If
Return MyBase.ProcessCmdKey(m, keyData)
End Function

As you can see, this function does not call MyBase.ProcessCmdKey if the
current user pressed the short cut key combination, so the underlying Edit
control code will not have chance to execute the default copy function.

So this behavior is by the design of ToolStripMenuItem.ShortcutKeys
property, although it looks strange.

Ok, we now know why the behavior is generated. I can provide a workaround
for this issue: simulate the underlying Edit control code in .Net.

The underlying Edit control actually monitors Ctrl+C key combination and
send a WM_COPY message to the Edit control to implement the default
function, so we can p/invoke SendMessage API and simulate this either.
Below is the sample code snippet for simulating the paste function:

Imports System.Runtime.InteropServices
Public Class Form1

<DllImport("user32.dll", CharSet:=CharSet.Auto)> _
Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As
Integer, ByVal wParam As Integer, ByVal lParam As Integer) As IntPtr
End Function

Private Const WM_PASTE As Integer = &H302
Private Sub PasteToolStripMenuItem_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles PasteToolStripMenuItem.Click
SendMessage(Me.ActiveControl.Handle, WM_PASTE, 0, 0)
End Sub
End Class

You can also handle CopyToolStripMenuItem, CutToolStripMenuItem's Click
event handler to send WM_COPY, WM_CUT messages.

Hope this helps! If you still have anything unclear, please feel free to
tell me, thanks!

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Hi Jeffrey,

Thanks for the response. Very thorough and helpful! I tried employing your
solution, and encountered some difficulty. Then I tried on a simple winforms
app with just a textbox and it worked properly. I think I figured out the
problem I'm now facing:

I set a breakpoint at:

SendMessage(Me.ActiveControl.Handle, WM_PASTE, 0, 0)

And examined what Me.ActiveControl is pointing to. The result:

{System.Windows.Forms.ToolStripContainer}

I would expect it to point to the textbox but that's not happening. I guess
it's not pointing deep enough in the control hierarchy. Do you know any way
to point deeper in the control hierarchy?

Thanks again for your help, Jeffrey...

-Ben

"Jeffrey Tan[MSFT]" said:
Hi Ben,

Thanks for your post!

Yes, I can reproduce this behavior. Let me clarify the internal work and
design to you:

1. The default Ctrl+C/V copy/paste behavior of TextBox is not implemented
by .Net, it is totally supported by underlying Win32 Edit control.(Note:
.Net TextBox control is a wrapper around Win32 Edit control). If you open
Notepad, the editing rectangle in it is a big Edit control(you may use
Spy++ to verify this), you will find that the Edit control of notepad will
have Ctrl+C/V copy/paste function defaultly.

2. After you adding standard menustrip to the Form, this behavior is lost.
It is prohibited by ToolStripMenuItem.ShortcutKeys property. You will find
that the following code in Form1.Designer.vb file(note: in hidden text):
Me.CopyToolStripMenuItem.ShortcutKeys =
CType((System.Windows.Forms.Keys.Control Or System.Windows.Forms.Keys.C),
System.Windows.Forms.Keys)

By using this code, .Net winform will intercept all the Ctrl+C key
combination and translate it into CopyToolStripMenuItem.Click event. If you
are curious, below is the source code that intercepts the short cut key and
fires the Click event:

Protected Friend Overrides Function ProcessCmdKey(ByRef m As Message, ByVal
keyData As Keys) As Boolean
If ((Me.Enabled AndAlso (Me.ShortcutKeys = keyData)) AndAlso Not
Me.HasDropDownItems) Then
MyBase.FireEvent(ToolStripItemEventType.Click)
Return True
End If
Return MyBase.ProcessCmdKey(m, keyData)
End Function

As you can see, this function does not call MyBase.ProcessCmdKey if the
current user pressed the short cut key combination, so the underlying Edit
control code will not have chance to execute the default copy function.

So this behavior is by the design of ToolStripMenuItem.ShortcutKeys
property, although it looks strange.

Ok, we now know why the behavior is generated. I can provide a workaround
for this issue: simulate the underlying Edit control code in .Net.

The underlying Edit control actually monitors Ctrl+C key combination and
send a WM_COPY message to the Edit control to implement the default
function, so we can p/invoke SendMessage API and simulate this either.
Below is the sample code snippet for simulating the paste function:

Imports System.Runtime.InteropServices
Public Class Form1

<DllImport("user32.dll", CharSet:=CharSet.Auto)> _
Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As
Integer, ByVal wParam As Integer, ByVal lParam As Integer) As IntPtr
End Function

Private Const WM_PASTE As Integer = &H302
Private Sub PasteToolStripMenuItem_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles PasteToolStripMenuItem.Click
SendMessage(Me.ActiveControl.Handle, WM_PASTE, 0, 0)
End Sub
End Class

You can also handle CopyToolStripMenuItem, CutToolStripMenuItem's Click
event handler to send WM_COPY, WM_CUT messages.

Hope this helps! If you still have anything unclear, please feel free to
tell me, thanks!

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Hi Jeffrey,

I think my thought was correct and I've found a solution that works:

Private Sub CopyToolStripMenuItem1_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles CopyToolStripMenuItem1.Click,
CopyToolStripMenuItem.Click
Dim thecontrol As Control
thecontrol = Me.ActiveControl

Dim mytsc As ToolStripContainer = TryCast(thecontrol,
ToolStripContainer)

If mytsc IsNot Nothing Then
SendMessage(mytsc.ActiveControl.Handle, WM_COPY, 0, 0)
Else
SendMessage(Me.ActiveControl.Handle, WM_COPY, 0, 0)
End If
End Sub

It only goes one level deep, but does the job. I was thinking of using a
loop that would keep going deeper until it couldn't grab an "activecontrol"
property, but at least in my app, this seems to work. Thanks again for your
help!

-Ben

Ben R. said:
Hi Jeffrey,

Thanks for the response. Very thorough and helpful! I tried employing your
solution, and encountered some difficulty. Then I tried on a simple winforms
app with just a textbox and it worked properly. I think I figured out the
problem I'm now facing:

I set a breakpoint at:

SendMessage(Me.ActiveControl.Handle, WM_PASTE, 0, 0)

And examined what Me.ActiveControl is pointing to. The result:

{System.Windows.Forms.ToolStripContainer}

I would expect it to point to the textbox but that's not happening. I guess
it's not pointing deep enough in the control hierarchy. Do you know any way
to point deeper in the control hierarchy?

Thanks again for your help, Jeffrey...

-Ben

"Jeffrey Tan[MSFT]" said:
Hi Ben,

Thanks for your post!

Yes, I can reproduce this behavior. Let me clarify the internal work and
design to you:

1. The default Ctrl+C/V copy/paste behavior of TextBox is not implemented
by .Net, it is totally supported by underlying Win32 Edit control.(Note:
.Net TextBox control is a wrapper around Win32 Edit control). If you open
Notepad, the editing rectangle in it is a big Edit control(you may use
Spy++ to verify this), you will find that the Edit control of notepad will
have Ctrl+C/V copy/paste function defaultly.

2. After you adding standard menustrip to the Form, this behavior is lost.
It is prohibited by ToolStripMenuItem.ShortcutKeys property. You will find
that the following code in Form1.Designer.vb file(note: in hidden text):
Me.CopyToolStripMenuItem.ShortcutKeys =
CType((System.Windows.Forms.Keys.Control Or System.Windows.Forms.Keys.C),
System.Windows.Forms.Keys)

By using this code, .Net winform will intercept all the Ctrl+C key
combination and translate it into CopyToolStripMenuItem.Click event. If you
are curious, below is the source code that intercepts the short cut key and
fires the Click event:

Protected Friend Overrides Function ProcessCmdKey(ByRef m As Message, ByVal
keyData As Keys) As Boolean
If ((Me.Enabled AndAlso (Me.ShortcutKeys = keyData)) AndAlso Not
Me.HasDropDownItems) Then
MyBase.FireEvent(ToolStripItemEventType.Click)
Return True
End If
Return MyBase.ProcessCmdKey(m, keyData)
End Function

As you can see, this function does not call MyBase.ProcessCmdKey if the
current user pressed the short cut key combination, so the underlying Edit
control code will not have chance to execute the default copy function.

So this behavior is by the design of ToolStripMenuItem.ShortcutKeys
property, although it looks strange.

Ok, we now know why the behavior is generated. I can provide a workaround
for this issue: simulate the underlying Edit control code in .Net.

The underlying Edit control actually monitors Ctrl+C key combination and
send a WM_COPY message to the Edit control to implement the default
function, so we can p/invoke SendMessage API and simulate this either.
Below is the sample code snippet for simulating the paste function:

Imports System.Runtime.InteropServices
Public Class Form1

<DllImport("user32.dll", CharSet:=CharSet.Auto)> _
Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As
Integer, ByVal wParam As Integer, ByVal lParam As Integer) As IntPtr
End Function

Private Const WM_PASTE As Integer = &H302
Private Sub PasteToolStripMenuItem_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles PasteToolStripMenuItem.Click
SendMessage(Me.ActiveControl.Handle, WM_PASTE, 0, 0)
End Sub
End Class

You can also handle CopyToolStripMenuItem, CutToolStripMenuItem's Click
event handler to send WM_COPY, WM_CUT messages.

Hope this helps! If you still have anything unclear, please feel free to
tell me, thanks!

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jeffrey Tan[MSFT]

Hi Ben,

Cool, you resolved this further issue before I reviewed it! You will
benifit more from figuring out yourself than learning from others :)

Additionally, if you know of your control hierarchy accurately, your code
snippet will just work without any problem. To develop a more general
solution, you may just loop through the control hierarchy and find the
deepest active control, like this:

<DllImport("user32.dll", CharSet:=CharSet.Auto)> _
Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As
Integer, ByVal wParam As Integer, ByVal lParam As Integer) As IntPtr
End Function

Private Const WM_PASTE As Integer = &H302
Private Sub PasteToolStripMenuItem_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles PasteToolStripMenuItem.Click
Dim cc As ContainerControl = Me
Dim ac As Control
Do
ac = cc.ActiveControl
Try
cc = CType(ac, ContainerControl)
Catch ex As Exception 'if the ActiveControl is not a
ContainerControl, an exception will throw
Exit Do 'We have found the
inner most control, so exit loop
End Try

Loop
SendMessage(ac.Handle, WM_PASTE, 0, 0)
End Sub

Hope this helps!

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

cut, copy, and paste 17
miplementing cut/copy/paste 1
Copy, Cut, Paste 13
Disable Cut/Copy/Paste in Excel 2010 0
Cut and paste 1
cut, copy, paste 9
Copy, Cut and Paste 3
Managing Cut/Copy & Paste During Program Run 1

Top