8

当我在 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-剪贴板.aspx

创建一个继承标签的新类,vb代码:

公共类 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

结束类

4

4 回答 4

17

这不是您的代码,而是 Windows Vista 中引入的“功能”。

在 Windows Vista 中,Windows Shell 程序员签入了一项更改(更改列表中没有规范/理由),该更改更改了默认标签控件,以便在双击时将其文本复制到剪贴板。

由于 C++ 应用程序创建/托管标签控件的方式,此更改通常不会影响它们,但会影响所有 VS.NET 应用程序。当我在 Win7 时间范围内发现这个问题时,我向(惊讶的)框架团队提出了一个错误,但他们害怕修复这个错误,因为它已经存在了很长时间。

这是重复的有没有办法禁用 .NET 标签的“双击复制”功能?

于 2013-06-11T16:00:19.580 回答
4

让标签在双击时不做出反应的最佳方法是通过覆盖标签类本身来覆盖类样式。

    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).aspx http://msdn.microsoft.com/en-us/library/system。 windows.forms.createparams(v=vs.110).aspx

于 2014-01-29T15:16:49.283 回答
1

我想有许多不同的方法可以解决同样的问题。这是我想出的(使用继承标签,在 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# 中备份和恢复系统剪贴板?

于 2017-10-07T10:08:30.250 回答
0

我已经为 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

于 2021-06-28T09:28:15.267 回答