Einfügen-Menue abhängig vom Clipboard aktivieren oder deaktivieren
Veröffentlicht: 09. Dez 2001 | Aktualisiert: 13. Jun 2004
Von Hening Schünke
Oft steht man vor dem Problem, das Clipboard in der eigenen Anwendung benutzen zu wollen. Jetzt soll aber der Menüpunkt "Bearbeiten.Einfügen" nur aktiv sein, wenn sich auch tatsächlich einfügbarer Text im Clipboard befindet. Dies lässt sich mit der Klasse MyClpBoard bewerkstelligen. Diese erzeugt ein Event auf der Form, in welchem das Datenformat abgefragt wird und dem entsprechend kann dann der Menüpunkt aktiviert werden. Den vollständigen Code dieser Klasse finden Sie am Ende dieses Artikels.
Diese Klasse bekommt aber nicht mit, ob das Clipboard von externen Programmen (Word etc.) mit Daten gefüllt wird. In diesem Fall findet ein Taskwechsel statt. Das heißt, der Anwender aktiviert Word und Ihre Anwendung verliert den Fokus. Wenn jetzt in Word Text ins Clipboard kopiert wurde, so genügt es zur korrekten Aktivierung des Menüs, wenn die Prüfung des Clipboard-Inhalts erfolgt, sobald Ihre Anwendung wieder aktiviert wird.
Hier hilft der Artikel Q186908. Dieser zeigt, wie mittels Subclassing der VB-Form die Windows-Message APPACTIVATE abgefangen wird, damit das VB-Programm erkennen kann, wenn es nach einer Taskumschaltung wieder aktiviert wird. Dann wird der Inhalt des Clipboards geprüft und in Abhängigkeit davon wird der Status des Menüpunktes gesetzt.
Ändern Sie das Beispiel aus Q186908 so ab, dass die Form ein Menü mit den Menüpunkten "Kopieren", "Einfügen" und "Zwischenablage löschen" enthält. Dabei sollte das Menü als Array mit den Indizes 0 bis 2 ausgeführt sein und das Menüobjekt sollte "mnuSubEdit" heißen.
Ergänzen Sie dann den Code der Form um die folgenden Teile:
' Deklaration der Klasseninstanz mit Events Private WithEvents mobjMyClipboard As MyClipboard Private Sub Form_Load() ' Festlegen der Klasseninstanz Set mobjMyClipboard = New MyClipboard '... schon aus Q186908 vorhandenen Code nicht ändern, nur die obige Zeile hinzufügen End Sub ' Sub wird als Reaktion auf die AppActivate Mesage aufgerufen Public Sub AppActivate() mobjMyClipboard.CheckClipboard End Sub Private Sub mnuSubEdit_Click(Index As Integer) Select Case Index Case 0 ' Kopieren mobjMyClipboard.SetClipboardText txtEdit.SelText Case 1 ' Einfügen txtEdit.SelText = mobjMyClipboard.GetClipboardText Case 2 ' Zwischenablage löschen mobjMyClipboard.ClearClipboard End Select End Sub Private Sub mobjMyClipboard_ClipboardChanged(DataFormat As Integer) mnuSubEdit(1).Enabled = (DataFormat <>0) End Sub
Im Modul MyClpBoard.bas wird der Code aus dem Artikel an die gewünschten Anforderungen angepasst.
Dazu wird lediglich die Prozedur "WindowProc" wie folgt geändert:
' Modul MyClpBoard.bas Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long 'Check for the ActivateApp message If (uMsg = WM_ACTIVATEAPP) And (wParam <>0) Then 'Check to see if Activating the application Form1.AppActivate End If 'Pass message on to the original window message handler WindowProc = CallWindowProc(lpPrevWndProc, hw, uMsg, wParam, lParam) End Function
Generell erklärt der Artikel Q170570, wie mittels Callback und AddressOf-Operator ein MessageHandler mit VB programmiert werden kann.
' Klasse MyClpBoard.cls Public Event ClipboardChanged(DataFormat As Integer) ' Text im Clipboard speichern Public Sub SetClipboardText(strText As String) Dim intFormat As Integer Clipboard.Clear Clipboard.SetText strText intFormat = GetDataFormat RaiseEvent ClipboardChanged(intFormat) End Sub ' Text aus Clipboard abrufen Public Function GetClipboardText() As String Dim strReturn As String strReturn = Clipboard.GetText GetClipboardText = strReturn End Function ' Clipboard loeschen Public Sub ClearClipboard() Dim intFormat As Integer Clipboard.Clear intFormat = GetDataFormat RaiseEvent ClipboardChanged(intFormat) End Sub ' Clipboard auf Inhalt prüfen Public Sub CheckClipboard() Dim intFormat As Integer intFormat = GetDataFormat RaiseEvent ClipboardChanged(intFormat) End Sub ' Welches Datenformat liegt vor ? Private Function GetDataFormat() As Integer Dim intReturn As Integer If Clipboard.GetFormat(vbCFLink) Then intReturn = vbCFLink End If If Clipboard.GetFormat(vbCFText) Then intReturn = vbCFText End If If Clipboard.GetFormat(vbCFBitmap) Then intReturn = vbCFBitmap End If If Clipboard.GetFormat(vbCFMetafile) Then intReturn = vbCFMetafile End If If Clipboard.GetFormat(vbCFDIB) Then intReturn = vbCFDIB End If If Clipboard.GetFormat(vbCFPalette) Then intReturn = vbCFPalette End If If (intReturn = vbCFText) And (Len(Clipboard.GetText) = 0) Then ' Wenn bei Datenformat Text die Laenge 0 ist, ist das Clipboard effektiv leer intReturn = 0 End If GetDataFormat = intReturn End Function