查看文章
 
关于清空Office的剪切板(一)
2008-04-25 7:50

关于清空Office剪切板的方法问题,原来好像就有很多的讨论。

1、有的大虾认为使用

Application.CutCopyMode = False

就可以了。其实不然,这只是取消剪切或复制模式并清除移动边框。并没有真正的清除剪切板上的数据。数据还是存在的。

2、使用API函数程序,代码如下:

Private Declare Function apiOpenClipboard Lib "user32" Alias "OpenClipboard" (ByVal hwnd As Long) As Long
Private Declare Function apiEmptyClipboard Lib "user32" Alias "EmptyClipboard" () As Long
Private Declare Function apiCloseClipboard Lib "user32" Alias "CloseClipboard" () As Long
Sub myClr()  
     apiOpenClipboard (0)'打开剪切板
     apiEmptyClipboard'清空剪切板
     apiCloseClipboard'关闭剪切板
End Sub

但是你会发现使用这段程序也不会清空Office的剪切板,这是因为Windows不会参与剪切板私有数据的管理。

3、前一段时间我看到一段代码,是用来清空Office的剪切板的,代码如下:

'---------------------------------------------------------------------------------------
'
Module      : Module1
'
DateTime : 12/4/2006 11:23
'
Author      : keepITcool , http://www.mrexcel.com/board2/viewtopic.php?t=143291                   
'
Purpose     : Clear Windows and Office Clipboards
'
---------------------------------------------------------------------------------------
Private Declare Function apiOpenClipboard Lib "user32" Alias "OpenClipboard" (ByVal hwnd As Long) As Long
Private Declare Function apiEmptyClipboard Lib "user32" Alias "EmptyClipboard" () As Long
Private Declare Function apiCloseClipboard Lib "user32" Alias "CloseClipboard" () As Long
Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
Private Declare Function FindWindowEx Lib "user32.dll" _
    
Alias "FindWindowExA" (ByVal hWnd1 As Long, _
    
ByVal hWnd2 As Long, ByVal lpsz1 As String, _
    
ByVal lpsz2 As String) As Long
Private Declare Function PostMessage Lib "user32.dll" Alias _
    
"PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, _
    
ByVal wParam As Long, ByVal lParam As Long) As Long
Private Const WM_LBUTTONDOWN As Long = &H201&
Private Const WM_LBUTTONUP As Long = &H202&

' Creates a long variable out of two words
Private Function MakeLong(ByVal nLoWord As Integer, ByVal nHiWord As Integer) As Long
      MakeLong
= nHiWord * 65536 + nLoWord
End Function


Sub ClearOfficeClipboard()
Dim hMain&, hExcel2&, hClip&, hWindow&, hParent&
Dim lParameter&, sTask$

sTask
= Application.CommandBars("Task Pane").NameLocal

' Handle for XLMAIN
hMain = Application.hwnd

' Find the OfficeClipboard Window
'
2 methods as we're not sure if it's visible
'
ONCE it has been made visible the windowclass is created
'
and remains loaded for the duration of the instance
Do
      hExcel2
= FindWindowEx(hMain, hExcel2, "EXCEL2", vbNullString)
      hParent
= hExcel2: hWindow = 0
      hWindow
= FindWindowEx(hParent, hWindow, "MsoCommandBar", sTask)
    
If hWindow Then
          hParent
= hWindow: hWindow = 0
          hWindow
= FindWindowEx(hParent, hWindow, "MsoWorkPane", vbNullString)
        
If hWindow Then
              hParent
= hWindow: hWindow = 0
              hClip
= FindWindowEx(hParent, hWindow, "bosa_sdm_XL9", vbNullString)
            
If hClip > 0 Then
                
Exit Do
            
End If
        
End If
    
End If
Loop While hExcel2 > 0

If hClip = 0 Then
      hParent
= hMain: hWindow = 0
      hWindow
= FindWindowEx(hParent, hWindow, "MsoWorkPane", vbNullString)
    
If hWindow Then
          hParent
= hWindow: hWindow = 0
          hClip
= FindWindowEx(hParent, hWindow, "bosa_sdm_XL9", vbNullString)
    
End If
End If

If hClip = 0 Then
      ClipWindowForce
      hParent
= hMain: hWindow = 0
      hWindow
= FindWindowEx(hParent, hWindow, "MsoWorkPane", vbNullString)
    
If hWindow Then
          hParent
= hWindow: hWindow = 0
          hClip
= FindWindowEx(hParent, hWindow, "bosa_sdm_XL9", vbNullString)
    
End If
End If


If hClip = 0 Then
    
MsgBox "Cant find Clipboard window"
    
Exit Sub
End If

lParameter
= MakeLong(120, 18)
Call PostMessage(hClip, WM_LBUTTONDOWN, 0&, lParameter)
Call PostMessage(hClip, WM_LBUTTONUP, 0&, lParameter)
Sleep
100
DoEvents

End Sub

Sub ClipWindowForce()
Dim octl
With Application.CommandBars("Task Pane")
    
If Not .Visible Then
          Application.ScreenUpdating
= False
        
Set octl = Application.CommandBars(1).FindControl(ID:=809, recursive:=True)
        
If Not octl Is Nothing Then octl.Execute
          .Visible
= False
          Application.ScreenUpdating
= True
    
End If
End With
End Sub

' Main program to clear Windows and Office Clipboards

Sub myClr()  

Call ClearOfficeClipboard
apiOpenClipboard (
0)
apiEmptyClipboard
apiCloseClipboard
Application.CutCopyMode
= False

End Sub

      代码的基本原理是找到剪切板窗体的句柄,然后向窗体发送一个在“全部清空”这个按钮的位置点击鼠标左键的消息,以此来清空剪切板。一开始我对这段代码进行了检测,发现他很有效果,真的可以清空Office的剪切板。并把它转载到了我的博客。但是后来我发现当剪切板的位置变为横放或者Office剪切板的大小发生变化导致“全部清空”的位置发生变化更有可能导致“全部清空”按钮不可见时,此代码就不能清空Office的剪切板(前两种情况可以用判断一下Office大小及位置的方法来发送消息来解决,但Office剪切板"全部清空"按钮不可见时就不好弄了)。
      可见以上的方法都不完美,不能真正的清空Office剪切板。

待续:关于清空Office的剪切板(二)


类别:excel杂记||添加到搜藏 |分享到i贴吧|浏览(1851)|评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
     

   
帮助中心 | 空间客服 | 投诉中心 | 空间协议
©2012 Baidu