以下是用richtextbox的菜单代码,关键是撤消/恢复,这部分在网上搜索到的精典代码'声明 '编辑器菜单撤消与恢复用 Private Declare Function SendMessage Lib "USER32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long Const WM_USER = &H400 Const EM_HIDESELECTION = WM_USER + 63 Dim TrapUndo As Boolean, UndoStack As New Collection, RedoStack As New Collection '窗体中创建菜单项目,名称请参照下面代码Private Sub RichTextBox1_SelChange() '菜单属性设置 Dim ln As Long If Not TrapUndo Then Exit Sub ln = RichTextBox1.SelLength mnuCut.Enabled = ln '不选择文本则禁用 mnuCopy.Enabled = ln '同上 mnuPaste.Enabled = Len(Clipboard.GetText(1)) '剪贴版为空则禁用 mnuDelete.Enabled = ln '不选择文本则禁用 mnuSelectALL.Enabled = CBool(Len(RichTextBox1.Text)) '文本框无内容则禁用 End SubPrivate Sub RichTextBox1_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single) '启动菜单 If Button = 2 Then PopupMenu mnuEdit End SubPrivate Sub mnuUndo_Click() '撤消 Dim chg As String, x As Long, deleteflag As Boolean Dim objelement As Object, objelement2 As Object On Error GoTo cuowu: If UndoStack.Count > 1 And TrapUndo Then TrapUndo = False deleteflag = UndoStack(UndoStack.Count - 1).TextLen < UndoStack(UndoStack.Count).TextLen If deleteflag Then x = SendMessage(RichTextBox1.hwnd, EM_HIDESELECTION, 1&, 1&) Set objelement = UndoStack(UndoStack.Count) Set objelement2 = UndoStack(UndoStack.Count - 1) RichTextBox1.SelStart = objelement.SelStart - (objelement.TextLen - objelement2.TextLen) RichTextBox1.SelLength = objelement.TextLen - objelement2.TextLen RichTextBox1.SelText = "" x = SendMessage(RichTextBox1.hwnd, EM_HIDESELECTION, 0&, 0&) Else Set objelement = UndoStack(UndoStack.Count - 1) Set objelement2 = UndoStack(UndoStack.Count) chg = Change(objelement.Text, objelement2.Text, _ objelement2.SelStart + 1 + Abs(Len(objelement.Text) - Len(objelement2.Text))) RichTextBox1.SelStart = objelement2.SelStart RichTextBox1.SelLength = 0 RichTextBox1.SelText = chg RichTextBox1.SelStart = objelement2.SelStart If Len(chg) > 1 And chg <> vbCrLf Then RichTextBox1.SelLength = Len(chg) Else RichTextBox1.SelStart = RichTextBox1.SelStart + Len(chg) End If End If RedoStack.Add Item:=UndoStack(UndoStack.Count) UndoStack.Remove UndoStack.Count End If EnableControls TrapUndo = True RichTextBox1.SetFocus Exit Sub cuowu: Set UndoStack = Nothing: Set RedoStack = Nothing: RichTextBox1_Change '初始化撤消与恢复 End SubPrivate Sub huifu_Click() '恢复 Dim chg As String, deleteflag As Boolean Dim objelement As Object On Error GoTo cuowu: If RedoStack.Count > 0 And TrapUndo Then TrapUndo = False deleteflag = RedoStack(RedoStack.Count).TextLen < Len(RichTextBox1.Text) If deleteflag Then Set objelement = RedoStack(RedoStack.Count) RichTextBox1.SelStart = objelement.SelStart RichTextBox1.SelLength = Len(RichTextBox1.Text) - objelement.TextLen RichTextBox1.SelText = "" Else Set objelement = RedoStack(RedoStack.Count) chg = Change(RichTextBox1.Text, objelement.Text, objelement.SelStart + 1) RichTextBox1.SelStart = objelement.SelStart - Len(chg) RichTextBox1.SelLength = 0 RichTextBox1.SelText = chg RichTextBox1.SelStart = objelement.SelStart - Len(chg) If Len(chg) > 1 And chg <> vbCrLf Then RichTextBox1.SelLength = Len(chg) Else RichTextBox1.SelStart = RichTextBox1.SelStart + Len(chg) End If End If UndoStack.Add Item:=objelement RedoStack.Remove RedoStack.Count End If EnableControls TrapUndo = True RichTextBox1.SetFocus Exit Sub cuowu: Set UndoStack = Nothing: Set RedoStack = Nothing: RichTextBox1_Change '初始化撤消与恢复 End SubPublic Function Change(ByVal lParam1 As String, ByVal lParam2 As String, startSearch As Long) As String Dim tempParam As String, d As Long If Len(lParam1) > Len(lParam2) Then tempParam = lParam1 lParam1 = lParam2 lParam2 = tempParam End If d = Len(lParam2) - Len(lParam1) Change = Mid(lParam2, startSearch - d, d) End FunctionPrivate Sub mnuCut_Click() '剪切 On Error GoTo 1 Clipboard.Clear 1 Clipboard.SetText RichTextBox1.SelText, 1 RichTextBox1.SelText = "" End Sub Private Sub mnuCopy_Click() '拷贝 On Error GoTo 1 Clipboard.Clear 1 Clipboard.SetText RichTextBox1.SelText, 1 End Sub Private Sub mnuPaste_Click() '粘贴 RichTextBox1.SelText = "" RichTextBox1.SelText = Clipboard.GetText(1) End Sub Private Sub mnuDelete_Click() '删除 RichTextBox1.SelText = "" End Sub Private Sub mnuSelectAll_Click() '全选 RichTextBox1.SelStart = 0 RichTextBox1.SelLength = Len(RichTextBox1.Text) End Sub
'编辑器菜单撤消与恢复用
Private Declare Function SendMessage Lib "USER32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long
Const WM_USER = &H400
Const EM_HIDESELECTION = WM_USER + 63
Dim TrapUndo As Boolean, UndoStack As New Collection, RedoStack As New Collection '窗体中创建菜单项目,名称请参照下面代码Private Sub RichTextBox1_SelChange() '菜单属性设置
Dim ln As Long
If Not TrapUndo Then Exit Sub
ln = RichTextBox1.SelLength
mnuCut.Enabled = ln '不选择文本则禁用
mnuCopy.Enabled = ln '同上
mnuPaste.Enabled = Len(Clipboard.GetText(1)) '剪贴版为空则禁用
mnuDelete.Enabled = ln '不选择文本则禁用
mnuSelectALL.Enabled = CBool(Len(RichTextBox1.Text)) '文本框无内容则禁用
End SubPrivate Sub RichTextBox1_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single) '启动菜单
If Button = 2 Then PopupMenu mnuEdit
End SubPrivate Sub mnuUndo_Click() '撤消
Dim chg As String, x As Long, deleteflag As Boolean
Dim objelement As Object, objelement2 As Object
On Error GoTo cuowu:
If UndoStack.Count > 1 And TrapUndo Then
TrapUndo = False
deleteflag = UndoStack(UndoStack.Count - 1).TextLen < UndoStack(UndoStack.Count).TextLen
If deleteflag Then
x = SendMessage(RichTextBox1.hwnd, EM_HIDESELECTION, 1&, 1&)
Set objelement = UndoStack(UndoStack.Count)
Set objelement2 = UndoStack(UndoStack.Count - 1)
RichTextBox1.SelStart = objelement.SelStart - (objelement.TextLen - objelement2.TextLen)
RichTextBox1.SelLength = objelement.TextLen - objelement2.TextLen
RichTextBox1.SelText = ""
x = SendMessage(RichTextBox1.hwnd, EM_HIDESELECTION, 0&, 0&)
Else
Set objelement = UndoStack(UndoStack.Count - 1)
Set objelement2 = UndoStack(UndoStack.Count)
chg = Change(objelement.Text, objelement2.Text, _
objelement2.SelStart + 1 + Abs(Len(objelement.Text) - Len(objelement2.Text)))
RichTextBox1.SelStart = objelement2.SelStart
RichTextBox1.SelLength = 0
RichTextBox1.SelText = chg
RichTextBox1.SelStart = objelement2.SelStart
If Len(chg) > 1 And chg <> vbCrLf Then
RichTextBox1.SelLength = Len(chg)
Else
RichTextBox1.SelStart = RichTextBox1.SelStart + Len(chg)
End If
End If
RedoStack.Add Item:=UndoStack(UndoStack.Count)
UndoStack.Remove UndoStack.Count
End If
EnableControls
TrapUndo = True
RichTextBox1.SetFocus
Exit Sub
cuowu:
Set UndoStack = Nothing: Set RedoStack = Nothing: RichTextBox1_Change '初始化撤消与恢复
End SubPrivate Sub huifu_Click() '恢复
Dim chg As String, deleteflag As Boolean
Dim objelement As Object
On Error GoTo cuowu:
If RedoStack.Count > 0 And TrapUndo Then
TrapUndo = False
deleteflag = RedoStack(RedoStack.Count).TextLen < Len(RichTextBox1.Text)
If deleteflag Then
Set objelement = RedoStack(RedoStack.Count)
RichTextBox1.SelStart = objelement.SelStart
RichTextBox1.SelLength = Len(RichTextBox1.Text) - objelement.TextLen
RichTextBox1.SelText = ""
Else
Set objelement = RedoStack(RedoStack.Count)
chg = Change(RichTextBox1.Text, objelement.Text, objelement.SelStart + 1)
RichTextBox1.SelStart = objelement.SelStart - Len(chg)
RichTextBox1.SelLength = 0
RichTextBox1.SelText = chg
RichTextBox1.SelStart = objelement.SelStart - Len(chg)
If Len(chg) > 1 And chg <> vbCrLf Then
RichTextBox1.SelLength = Len(chg)
Else
RichTextBox1.SelStart = RichTextBox1.SelStart + Len(chg)
End If
End If
UndoStack.Add Item:=objelement
RedoStack.Remove RedoStack.Count
End If
EnableControls
TrapUndo = True
RichTextBox1.SetFocus
Exit Sub
cuowu:
Set UndoStack = Nothing: Set RedoStack = Nothing: RichTextBox1_Change '初始化撤消与恢复
End SubPublic Function Change(ByVal lParam1 As String, ByVal lParam2 As String, startSearch As Long) As String
Dim tempParam As String, d As Long
If Len(lParam1) > Len(lParam2) Then
tempParam = lParam1
lParam1 = lParam2
lParam2 = tempParam
End If
d = Len(lParam2) - Len(lParam1)
Change = Mid(lParam2, startSearch - d, d)
End FunctionPrivate Sub mnuCut_Click() '剪切
On Error GoTo 1
Clipboard.Clear
1
Clipboard.SetText RichTextBox1.SelText, 1
RichTextBox1.SelText = ""
End Sub
Private Sub mnuCopy_Click() '拷贝
On Error GoTo 1
Clipboard.Clear
1
Clipboard.SetText RichTextBox1.SelText, 1
End Sub
Private Sub mnuPaste_Click() '粘贴
RichTextBox1.SelText = ""
RichTextBox1.SelText = Clipboard.GetText(1)
End Sub
Private Sub mnuDelete_Click() '删除
RichTextBox1.SelText = ""
End Sub
Private Sub mnuSelectAll_Click() '全选
RichTextBox1.SelStart = 0
RichTextBox1.SelLength = Len(RichTextBox1.Text)
End Sub
Clipboard.SetText "aaaaaaaa"
不熟悉快捷键的人也会按右键阿,只要你程序中的TEXT控件的ENABLE没有被设为FALSE,运行时按下右键都会弹出复制剪切粘贴的菜单来的。楼主不信的话自己试试,新建个工程,窗体上放个TEXT,什么代码都不写,直接按F5运行,对着它按鼠标右键试试就知道了。
但我要得是我在其它自己定义的菜单上实现这些功能。