在Vista+?上双击.NET标签控件将其文本复制到剪贴板

wlzqhblo  于 2023-05-19  发布在  .NET
关注(0)|答案(4)|浏览(187)

当我在visual studio中搜索整个项目中的“剪贴板”一词时,我没有找到匹配项。
然而,不知何故,我的程序似乎正在更改剪贴板的内容,使其等于窗体上某个控件的.text属性。怎么会这样?
我已经确定了我的剪贴板似乎总是被改变的处理程序,并添加了一个消息框来从我的剪贴板中获取文本,以尝试识别何时可能被改变。

MessageBox.Show(Clipboard.GetText)

即使在处理事件的子程序的顶部,我的剪贴板也已经被更改为控件的.text属性。这是处理此事件的唯一子程序,并且剪贴板在此事件后始终更改。
这是一个用vb.net编写的小型winforms项目。

更多信息:

当我点击一个标签时,我的剪贴板被设置为标签的.text属性。标签在这里制作:

For i = 0 To lstTupChildren.Count - 1
        Dim lbl As New Label()
        lbl.Size = New System.Drawing.Size(250, 25)
        lbl.Font = New System.Drawing.Font("Calibri (body)", 10)
        lbl.Text = i + 1 & ". " & lstTupChildren(i).Item1
        lbl.Location = New System.Drawing.Point(0, 25 * i)
        If lstTupChildren(i).Item3 = True Then lbl.BackColor = Color.GreenYellow Else lbl.BackColor = Color.Orange 'sets the colour depending on whether the timesheet is active'
            Me.Controls.Add(lbl)
            AddHandler lbl.DoubleClick, AddressOf subChangeTimesheetState 'adds handler for double click to change status
            'adds handlers for moving the overlay
            AddHandler lbl.MouseDown, AddressOf Form_MouseDown
            AddHandler lbl.MouseMove, AddressOf Form_MouseMove
            'adds handler for hide context menu'
            AddHandler lbl.MouseClick, AddressOf subRightClickMenu

        Next

即使我注解掉处理程序:

AddHandler lbl.DoubleClick, AddressOf subChangeTimesheetState

我的剪贴板还在变化。
解决方法可在此处找到:
http://www.aspnet-answers.com/microsoft/NET-WinForms-Controls/32231136/double-click-label-and-its-text-appears-on-the-clipboard.aspx
创建一个继承标签的新类,vb代码:

Public Class myLabel

    Inherits Label
    Private WM_GETTEXT As Integer = &HD
    Private WM_LBUTTONDBLCLK As Integer = &H203
    Private doubleclickflag As Boolean = False
    Protected Overrides Sub WndProc(ByRef m As Message)
        If m.Msg = WM_LBUTTONDBLCLK Then
            doubleclickflag = True
        End If
        If m.Msg = WM_GETTEXT AndAlso doubleclickflag Then
            doubleclickflag = False
            Return
        End If
        MyBase.WndProc(m)
    End Sub

End Class
inkz8wg9

inkz8wg91#

这不是你的代码,这是Windows Vista中引入的一个“功能”。
在Windows Vista中,Windows Shell程序员签入了一项更改(更改列表中没有规范/理由),该更改更改了默认标签控件,以便在双击时将其文本复制到剪贴板。
由于C应用程序创建/托管label控件的方式,这种更改通常不会影响C应用程序,但它会影响所有VS.NET应用程序。当我在Win7的时间框架中发现这个问题时,我向(惊讶的)框架团队提交了一个错误,但是他们害怕修复这个错误,因为它已经存在了很长时间。
这是重复的Is there any way to disable the "double-click to copy" functionality of a .NET label?

jpfvwuh4

jpfvwuh42#

要使标签不对双击做出React,最好的方法是通过覆盖标签类本身来覆盖类样式。

private class SingleClickLabel : Label
    {
        protected override CreateParams CreateParams
        {
            get
            {
                new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();

                CreateParams cp = base.CreateParams;
                cp.ClassStyle &= ~0x0008;
                cp.ClassName = null;

                return cp;
            }
        }
    }

这将从标签中删除CS_DBLCLKS窗类样式。从现在起,将触发的唯一事件是每次单击所发生的Click事件。
参见:http://msdn.microsoft.com/en-us/library/windows/desktop/ff729176(v=vs.85).aspxhttp://msdn.microsoft.com/en-us/library/system.windows.forms.createparams(v=vs.110).aspx

y1aodyip

y1aodyip3#

我想有很多不同的方法来解决这个问题。以下是我的想法(使用继承的标签,在Windows Server 2012 R2上测试):

public class MyLabel : System.Windows.Forms.Label
{
    private const int WM_LBUTTONDBLCLK = 0x203;

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_LBUTTONDBLCLK)
        {
            string sSaved = Clipboard.GetText();
            System.Drawing.Image iSaved = Clipboard.GetImage();
            base.WndProc(ref m);
            if (iSaved != null) Clipboard.SetImage(iSaved);
            if (!string.IsNullOrEmpty(sSaved)) Clipboard.SetText(sSaved);
        }
        else
        {
            base.WndProc(ref m);
        }
    }
}

必须投入一些额外的精力来保存复制的Excel字段等,尽管原理是一样的。如前所述,您可以在剪贴板上迭代所有可用的格式(或您关心的格式),并将这些值填充到Dictionary对象中,然后在后面恢复它们。文字和图片涵盖了它,在这种情况下。
关于这个问题的一个有价值的链接在这里:如何在C#中备份和还原系统剪贴板?

o2g1uqev

o2g1uqev4#

  • 我为Visual Basic NET开发了此代码。这样当双击Label控件时,其文本不会自动复制到Windows剪贴板,其双击事件也可以使用。所需的是使用第二个标签,其属性与我们正在使用的标签相同。*
Private TimeSpan1 As New TimeSpan
Private CursorPos1 As Point
Private Declare Function GetDoubleClickTime Lib "user32" Alias "GetDoubleClickTime" () As Integer

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    With Label2
        .Text = Label1.Text
        .BackColor = Label1.BackColor
        .Location = Label1.Location
        .Size = Label1.Size
        ' and other visual properties (if different)
    End With
End Sub

Private Sub Label1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
    Handles Label1.MouseDown, Label2.MouseDown

    sender.SendToBack()  

    If (CursorPos1.X = Cursor.Position.X) And (CursorPos1.Y = Cursor.Position.Y) Then
        TimeSpan1 = Now - CDate(Label1.Tag)
        If TimeSpan1.TotalMilliseconds < GetDoubleClickTime Then
           
        '  Label1_DoubleClick event code 

        End If
    End If

    CursorPos1 = Cursor.Position
    Label1.Tag = Now

End Sub

相关问题