2013-06-11 12 views
7

Kiedy przeszukuję cały mój projekt w visual studio pod kątem słowa "schowek", nie znajduję żadnych dopasowań.Dwukrotne kliknięcie formantu .NET Label kopiuje swój tekst do schowka w systemie Vista +?

Jednak jakoś mój program wydaje się zmieniać zawartość mojego schowka, aby była równa właściwości .text formantu w moim formularzu. Jak to może być?

Zidentyfikowałem handler, po którym mój schowek zawsze wydaje się być zmieniony i dodano skrzynkę wiadomości, aby pobrać tekst z mojego schowka, aby spróbować określić, kiedy może on ulec zmianie.

MessageBox.Show(Clipboard.GetText) 

Nawet w górnej części podrzędnej obsługi zdarzenia mój schowek został już zmieniony na właściwość .text formantu. Jest to jedyny sub, który obsługuje to zdarzenie, a schowek zawsze zmienia się po tym wydarzeniu.

To jest mały projekt WinForm napisany w vb.net.

Więcej informacji:

Mój schowek jest uzyskiwanie ustawione na posesji .text etykiety po kliknięciu na nim. Etykiety wykonane są tutaj:

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 

nawet kiedy zakomentuj Handler: AddHandler lbl.DoubleClick, AddressOf subChangeTimesheetState

mój schowek jest ciągle zmieniane.

obejścia jest dostępny tutaj: obejść tutaj: http://www.aspnet-answers.com/microsoft/NET-WinForms-Controls/32231136/double-click-label-and-its-text-appears-on-the-clipboard.aspx

utworzyć nową klasę, która dziedziczy etykiecie kodu VB:

Klasa publiczna 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

+0

Więc jeśli usunąć obsługi, nie zmieni? –

+1

Jaki to rodzaj kontroli? Tylko pole tekstowe lub coś innego? –

+0

To jest doskonałe pytanie @ZachJohnson – 5uperdan

Odpowiedz

12

To nie jest twój kod, to "funkcja" wprowadzona w systemie Windows Vista.

W systemie Windows Vista programista powłoki systemu Windows zaznaczył zmianę (bez specyfikacji/uzasadnienia w liście zmian), która zmieniła domyślne sterowanie etykietą, aby skopiować jego tekst do schowka po dwukrotnym kliknięciu.

Ta zmiana zwykle nie wpływa na aplikacje w C++ ze względu na sposób tworzenia/hostowania kontroli etykiet, ale ma wpływ na wszystkie aplikacje VS.NET. Zgłaszałem błąd przeciwko zespołowi (zaskoczonemu) Framework, gdy odkryłem to w ramce czasowej Win7, ale bali się naprawić błąd, ponieważ był on obecny przez tak długi czas.

Oto duplikat Is there any way to disable the "double-click to copy" functionality of a .NET label?

+1

OMG TO PRAWDA! JESTEM TAK POSTĄPIONY, NIE MOGĘ WYŁĄCZYĆ CAPSLOCK. – 5uperdan

+0

+1. Taka świetna funkcja! Nie wiedziałem, że możesz to zrobić. Nie działa jednak na klasie messagebox, prawdopodobnie dlatego, że jest pod maską COM. – Neolisk

+0

FWIW: Nie sądzę, że MessageBox w ogóle używa COM; możesz wywołać go w aplikacji, która nigdy nie wywołuje CoInitialize. – EricLaw

4

Najlepszym sposobem, aby uzyskać etykietę, aby nie reagować na podwójnym kliknięciem ma zastąpić styl klasy nadrzędnymi samej klasy etykiety.

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; 
      } 
     } 
    } 

To usuwa styl klasy okna CS_DBLCLKS z etykiety. Jedynym zdarzeniem, które zostanie uruchomione od teraz, jest zdarzenie Click dla każdego kliknięcia, które ma miejsce.

Patrz: 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

+0

Co jeśli problem polega na tym, że dwukrotne kliknięcie na etykiecie jest w pewnych okolicznościach wymagane w programie, ale nie chcę tego, aby wyczyścić schowek? Pomyśl o palecie kolorów w programie do edycji obrazu otwierającym program wyboru koloru za pomocą dwukrotnego kliknięcia. – Nyerguds

1

Przypuszczam, istnieje wiele różnych sposobów, aby rozwiązać ten sam problem. Oto co wymyśliłem (przy użyciu odziedziczony etykietę, przetestowany w systemie 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); 
     } 
    } 
} 

Niektóre dodatkowy wysiłek będzie musiał być inwestowane w celu zachowania rzeczy jak skopiowanych pól Excel i tym podobne, chociaż zasady byłby taki sam. Jak wspomniano, możesz wykonać iterację w schowku dla wszystkich dostępnych formatów (lub tych, na których Ci zależy) i wprowadzić te wartości do obiektu Dictionary, a następnie przywrócić je. Tekst i zdjęcia pokrywają to dla mnie, w tym przypadku.

Jedno warto zobaczyć link na ten temat jest tutaj: How do I backup and restore the system clipboard in C#?

Powiązane problemy