如何在 MS Access VBA 中获取 MSForms.DataObject 内容的大小
How to get the size of the contents of MSForms.DataObject in MS Access VBA
我已将 BMP 图像复制到剪贴板,我会将其粘贴到 MS Access (2016) 中的表单对象框架控件中。
我需要知道的是图像在剪贴板上占用的内存大小(尽管如果有必要的话,如果有办法在对象框架控件中之后获取大小信息就可以了)。比如图片是76582字节还是652字节还是942002字节等等?
这是我用来将剪贴板中的图像粘贴到对象框架控件中的代码:
With Me.imgGrabbedFrame 'Bound Object Frame control
.Class = "Paintbrush Picture"
.OLETypeAllowed = acOLEEmbedded
.Action = acOLEPaste
End With
有没有办法获取剪贴板上对象占用的内存?
您可以将此函数与图像控件的属性部分中的图像 url 路径的字符串值一起使用
FileLen("C:\Temp\test file.xls")
你可以只计算框架值属性的长度。这包括任何 OLE meta-information.
LenB(Me.imgGrabbedFrame.Value)
return 值是以字节为单位的长度。
在剪贴板上计算它是可能的,但要复杂得多。
为此,首先,让我们定义几个函数来处理剪贴板:
Public Declare PtrSafe Function GetClipboardFormatNameW Lib "User32" (ByVal format As Long, ByVal lpszFormatName As LongPtr, ByVal cchMaxCount As Long) As Long
Public Declare PtrSafe Function OpenClipboard Lib "User32" (Optional ByVal hWndNewOwner As LongPtr) As Boolean
Public Declare PtrSafe Function CloseClipboard Lib "User32" () As Boolean
Public Declare PtrSafe Function EnumClipboardFormats Lib "User32" (ByVal format As Long) As Long
Public Declare PtrSafe Function CountClipboardFormats Lib "User32" () As Long
Public Declare PtrSafe Function GlobalSize Lib "Kernel32" (ByVal hMem As LongPtr) As LongPtr
Public Declare PtrSafe Function GetClipboardData Lib "User32" (ByVal uFormat As Long) As LongPtr
然后,让我们定义一个函数来迭代剪贴板上的不同格式:
Public Sub ListClipboardFormats()
Dim l As Long
Dim format As Long
Dim b As String
OpenClipboard
b = String(255, vbNullChar)
For l = 1 To CountClipboardFormats
format = EnumClipboardFormats(format)
GetClipboardFormatNameW format, StrPtr(b), 255
If Left(b, 1) = vbNullChar Then
Debug.Print format
Else
Debug.Print b
End If
b = String(255, vbNullChar)
Next
CloseClipboard
End Sub
此函数会将所有可用的剪贴板格式打印到即时 window。如果它是 built-in 格式,它将打印一个数字。您可以找到数字列表 here。图像数据的常见数字是 8,对于 CF_DIB,device-independent 位图,或 17 对于 CF_DIBV5,同一事物的更现代变体。
如果我们想使用其中一种自定义格式,让我们定义一个函数来获取它的编号。如果出现错误或 non-existent 剪贴板格式,此函数将 return 0:
Public Function GetClipboardFormatByName(strName As String) As Long
Dim format As Long
Dim b As String
Dim l As Long
OpenClipboard
For l = 1 To CountClipboardFormats
b = String(255, vbNullChar) 'Initialize string buffer
format = EnumClipboardFormats(format) 'Get next format
GetClipboardFormatNameW format, StrPtr(b), 255 'Copy name to buffer
If Left(b, Len(strName)) = strName Then
GetClipboardFormatByName = format
Exit Function
End If
Next
CloseClipboard
End Function
然后,如果我们有其格式,则确定剪贴板上内容大小的最终函数:
Public Function GetClipboardLength(ClipboardFormat As Long) As Long
OpenClipboard
Dim hClipboardGlobal As LongPtr
hClipboardGlobal = GetClipboardData(ClipboardFormat)
If hClipboardGlobal <> 0 Then
GetClipboardLength = GlobalSize(hClipboardGlobal)
End If
CloseClipboard
End Function
如果我们知道剪贴板上有一个 DIB,那么获取它的大小就像 GetClipboardLength(8)
一样简单。请注意,这是 DIB 的大小,并且在粘贴时可能实际上与数据的大小不相同,因为它被保存,因为可能会进行额外的处理。
关于剪贴板上大小的说明:剪贴板上的大小可能大于或小于您粘贴的大小,具体取决于实施方式。程序可以(而且经常会)将同一事物的多种表示形式(文本、富文本、图像、OLE 数据对象)放在剪贴板上,也可以以仅在访问时复制的方式将其放在那里。这就是为什么在复制大型对象后关闭 Office 程序时,系统经常会询问您是否要将该对象保留在剪贴板上。
我已将 BMP 图像复制到剪贴板,我会将其粘贴到 MS Access (2016) 中的表单对象框架控件中。
我需要知道的是图像在剪贴板上占用的内存大小(尽管如果有必要的话,如果有办法在对象框架控件中之后获取大小信息就可以了)。比如图片是76582字节还是652字节还是942002字节等等?
这是我用来将剪贴板中的图像粘贴到对象框架控件中的代码:
With Me.imgGrabbedFrame 'Bound Object Frame control
.Class = "Paintbrush Picture"
.OLETypeAllowed = acOLEEmbedded
.Action = acOLEPaste
End With
有没有办法获取剪贴板上对象占用的内存?
您可以将此函数与图像控件的属性部分中的图像 url 路径的字符串值一起使用
FileLen("C:\Temp\test file.xls")
你可以只计算框架值属性的长度。这包括任何 OLE meta-information.
LenB(Me.imgGrabbedFrame.Value)
return 值是以字节为单位的长度。
在剪贴板上计算它是可能的,但要复杂得多。
为此,首先,让我们定义几个函数来处理剪贴板:
Public Declare PtrSafe Function GetClipboardFormatNameW Lib "User32" (ByVal format As Long, ByVal lpszFormatName As LongPtr, ByVal cchMaxCount As Long) As Long
Public Declare PtrSafe Function OpenClipboard Lib "User32" (Optional ByVal hWndNewOwner As LongPtr) As Boolean
Public Declare PtrSafe Function CloseClipboard Lib "User32" () As Boolean
Public Declare PtrSafe Function EnumClipboardFormats Lib "User32" (ByVal format As Long) As Long
Public Declare PtrSafe Function CountClipboardFormats Lib "User32" () As Long
Public Declare PtrSafe Function GlobalSize Lib "Kernel32" (ByVal hMem As LongPtr) As LongPtr
Public Declare PtrSafe Function GetClipboardData Lib "User32" (ByVal uFormat As Long) As LongPtr
然后,让我们定义一个函数来迭代剪贴板上的不同格式:
Public Sub ListClipboardFormats()
Dim l As Long
Dim format As Long
Dim b As String
OpenClipboard
b = String(255, vbNullChar)
For l = 1 To CountClipboardFormats
format = EnumClipboardFormats(format)
GetClipboardFormatNameW format, StrPtr(b), 255
If Left(b, 1) = vbNullChar Then
Debug.Print format
Else
Debug.Print b
End If
b = String(255, vbNullChar)
Next
CloseClipboard
End Sub
此函数会将所有可用的剪贴板格式打印到即时 window。如果它是 built-in 格式,它将打印一个数字。您可以找到数字列表 here。图像数据的常见数字是 8,对于 CF_DIB,device-independent 位图,或 17 对于 CF_DIBV5,同一事物的更现代变体。
如果我们想使用其中一种自定义格式,让我们定义一个函数来获取它的编号。如果出现错误或 non-existent 剪贴板格式,此函数将 return 0:
Public Function GetClipboardFormatByName(strName As String) As Long
Dim format As Long
Dim b As String
Dim l As Long
OpenClipboard
For l = 1 To CountClipboardFormats
b = String(255, vbNullChar) 'Initialize string buffer
format = EnumClipboardFormats(format) 'Get next format
GetClipboardFormatNameW format, StrPtr(b), 255 'Copy name to buffer
If Left(b, Len(strName)) = strName Then
GetClipboardFormatByName = format
Exit Function
End If
Next
CloseClipboard
End Function
然后,如果我们有其格式,则确定剪贴板上内容大小的最终函数:
Public Function GetClipboardLength(ClipboardFormat As Long) As Long
OpenClipboard
Dim hClipboardGlobal As LongPtr
hClipboardGlobal = GetClipboardData(ClipboardFormat)
If hClipboardGlobal <> 0 Then
GetClipboardLength = GlobalSize(hClipboardGlobal)
End If
CloseClipboard
End Function
如果我们知道剪贴板上有一个 DIB,那么获取它的大小就像 GetClipboardLength(8)
一样简单。请注意,这是 DIB 的大小,并且在粘贴时可能实际上与数据的大小不相同,因为它被保存,因为可能会进行额外的处理。
关于剪贴板上大小的说明:剪贴板上的大小可能大于或小于您粘贴的大小,具体取决于实施方式。程序可以(而且经常会)将同一事物的多种表示形式(文本、富文本、图像、OLE 数据对象)放在剪贴板上,也可以以仅在访问时复制的方式将其放在那里。这就是为什么在复制大型对象后关闭 Office 程序时,系统经常会询问您是否要将该对象保留在剪贴板上。