Всем доброго времени суток!
Вопрос такого характера.
Есть модудь класса CPictureData
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239. 240. 241. 242. 243. 244. 245. 246. 247. 248. 249. 250. 251. 252. 253. 254. 255. 256. 257. 258. 259. 260. 261. 262. 263. 264. 265. 266. 267. 268. 269. 270. 271. 272. 273. 274. 275. 276. 277. 278. 279. 280. 281. 282. 283. 284. 285. 286. 287. 288. 289. 290. 291. 292. 293. 294. 295. 296. 297. 298. 299. 300. 301. 302. 303. 304. 305. 306. 307. 308. 309. 310. 311. 312. 313. 314. 315. 316. 317. 318. 319. 320. 321. 322. 323. 324. 325. 326. 327. 328. 329. 330. 331. 332. 333. 334. 335. 336. 337. 338. 339. 340. 341.
'Класс для загрузки изображения в Access.Image через свойство Picture,
'либо через свойство PictureData.
Option Compare Database
Option Explicit
'---------------- Описания структур, функций, констант Win32 API ---------------
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type BITMAP '24 bytes
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End Type
Private Declare Function SelectObject Lib "gdi32" ( _
ByVal hDC As Long, ByVal hObject As Long) As Long
Private Declare Function GetObjectA Lib "gdi32" ( _
ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function GetObjectType Lib "gdi32" ( _
ByVal hgdiobj As Long) As Long
Private Const OBJ_BITMAP = 7
Private Const OBJ_ENHMETAFILE = 13
Private Declare Function GetDC Lib "user32" ( _
ByVal hWnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32" ( _
ByVal hWnd As Long, ByVal hDC As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" ( _
ByVal hDC As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" ( _
ByVal hDC As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32" ( _
ByVal hDC As Long, ByVal nIndex As Long) As Long
Private Const HORZSIZE = 4 ' Horizontal size in millimeters
Private Const VERTSIZE = 6 ' Vertical size in millimeters
Private Const HORZRES = 8 ' Horizontal width in pixels
Private Const VERTRES = 10 ' Vertical width in pixels
Private Const LOGPIXELSX = 88 ' Logical pixels/inch in X
Private Const LOGPIXELSY = 90 ' Logical pixels/inch in Y
Private Declare Function CreateEnhMetaFile Lib "gdi32" _
Alias "CreateEnhMetaFileA" ( _
ByVal hdcRef As Long, ByVal lpFileName As String, lpRect As RECT, _
ByVal lpDescription As String) As Long
Private Declare Function CloseEnhMetaFile Lib "gdi32" ( _
ByVal hDC As Long) As Long
Private Declare Function DeleteEnhMetaFile Lib "gdi32" ( _
ByVal hEMF As Long) As Long
Private Declare Function GetEnhMetaFileBits Lib "gdi32" ( _
ByVal hEMF As Long, ByVal cbBuffer As Long, lpbBuffer As Any) As Long
Private Declare Function SetMapMode Lib "gdi32" ( _
ByVal hDC As Long, ByVal nMapMode As Long) As Long
Private Const MM_ANISOTROPIC = 8 ' Map mode anisotropic
Private Declare Function SetWindowExtEx Lib "gdi32" ( _
ByVal hDC As Long, ByVal nX As Long, ByVal nY As Long, _
lpSize As Any) As Long
Private Declare Function SetViewportExtEx Lib "gdi32" ( _
ByVal hDC As Long, ByVal nX As Long, _
ByVal nY As Long, lpSize As Any) As Long
Private Declare Function SetStretchBltMode Lib "gdi32" ( _
ByVal hDC As Long, ByVal nStretchMode As Long) As Long
Private Const STRETCH_DELETESCANS = 3
Private Const STRETCH_HALFTONE = 4
Private Declare Function BitBlt Lib "gdi32" ( _
ByVal hdcDest As Long, ByVal x As Long, ByVal y As Long, _
ByVal nWidth As Long, ByVal nHeight As Long, ByVal hdcSrc As Long, _
ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Const SRCCOPY = &HCC0020 ' (DWORD) dest = source
Private Const CF_ENHMETAFILE = 14
Private Type OSVERSIONINFO
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
szCSDVersion As String * 128 ' Maintenance string for PSS usage
End Type
Private Const VER_PLATFORM_WIN32_NT = 2
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" ( _
lpVersionInformation As OSVERSIONINFO) As Long
'-------------------------------------------------------------------------------
Public Enum PictureQuality
'pqLow
pqMedium
pqHigh
End Enum
Private Type TQuadBytes
bByte(0 To 3) As Byte
End Type
Private Type TLong
lLong As Long
End Type
Private m_hEMF As Long
Private m_pqQuality As PictureQuality
Private m_bIsNT As Boolean
Private Sub ReleaseResources()
If m_hEMF Then
DeleteEnhMetaFile m_hEMF
m_hEMF = 0
End If
End Sub
Private Sub Class_Initialize()
Dim ovi As OSVERSIONINFO
ovi.dwOSVersionInfoSize = Len(ovi)
GetVersionEx ovi
m_bIsNT = ovi.dwPlatformId >= VER_PLATFORM_WIN32_NT
If m_bIsNT Then m_pqQuality = pqHigh Else m_pqQuality = pqMedium
End Sub
Private Sub Class_Terminate()
ReleaseResources
End Sub
Public Property Get Quality() As PictureQuality
Quality = m_pqQuality
End Property
Public Property Let Quality(ByVal NewQuality As PictureQuality)
If (NewQuality >= pqMedium) And (NewQuality <= pqHigh) Then
If (NewQuality < pqHigh) Or m_bIsNT Then
m_pqQuality = NewQuality
Else
m_pqQuality = pqMedium
End If
Else
Err.Raise 5
End If
End Property
Public Function LoadFromFile(ByVal FileName As String, _
Image As Access.Image) As Boolean
Dim Pic As IPictureDisp
Dim sExtension As String
Dim nDotPos As Integer
ReleaseResources
'Выделение расширения имени файла, принятие решения, идти по длинному пути
'или по короткому.
FileName = Trim$(FileName)
nDotPos = InStrRev(FileName, ".")
If nDotPos > InStrRev(FileName, "\") Then
sExtension = UCase$(Mid$(FileName, nDotPos + 1))
Select Case sExtension
Case "WMF", "EMF", "ICO", "BMP", "DIB":
If (m_pqQuality < pqHigh) Or _
(sExtension <> "BMP") And (sExtension <> "DIB") Then
'Считаем, что окно фильтра для простых форматов не появляется,
'грузим изображение через свойство Picture.
On Error Resume Next
Image.Picture = FileName
LoadFromFile = Err = 0
On Error GoTo 0
Exit Function
End If
End Select
End If
On Error Resume Next
Set Pic = LoadPicture(FileName)
On Error GoTo 0
If Pic Is Nothing Then
'Ещё попытка - для форматов типа PNG, PCX, TGA, не понимаемых LoadPicture
On Error Resume Next
Image.Picture = FileName
LoadFromFile = Err = 0
On Error GoTo 0
Exit Function
End If
LoadFromFile = LoadFromIPicture(Pic, Image, True)
End Function
Public Function LoadFromIPicture( _
SrcPic As IPictureDisp, ByVal Image As Access.Image, _
Optional ByVal ReleasePicRef As Boolean = False) As Boolean
Dim rc As RECT
Dim hwndParent As Long
Dim hdcRef As Long
Dim hdcMeta As Long
Dim hdcMem As Long
Dim bm As BITMAP
Dim cbSize As Long
Dim cbCopied As Long
Dim hbmpOld As Long
Dim iWidthMM As Long
Dim iHeightMM As Long
Dim iWidthPels As Long
Dim iHeightPels As Long
Dim iDPIX As Long
Dim iDPIY As Long
Dim hEMF As Long
'Загрузка изображения через свойство PictureData.
ReleaseResources
'Ожидается pic.Type=vbPicTypeBitmap=1,GetObjectType(pic.Handle)=OBJ_BITMAP=7,
'или pic.Type=vbPicTypeEMetafile=4,GetObjectType(pic.Handle)=OBJ_ENHMETAFILE=13
Select Case GetObjectType(SrcPic.Handle)
Case OBJ_BITMAP:
'Получаем заголовок битмапа, чтобы извлечь из него размеры изображения
'в пикселях
cbSize = LenB(bm)
cbCopied = GetObjectA(SrcPic.Handle, cbSize, bm)
If cbCopied <> cbSize Then Exit Function
On Error Resume Next
hwndParent = ParentForm(Image).hWnd
On Error GoTo 0
hdcRef = GetDC(hwndParent)
iWidthMM = GetDeviceCaps(hdcRef, HORZSIZE)
iHeightMM = GetDeviceCaps(hdcRef, VERTSIZE)
iWidthPels = GetDeviceCaps(hdcRef, HORZRES)
iHeightPels = GetDeviceCaps(hdcRef, VERTRES)
iDPIX = GetDeviceCaps(hdcRef, LOGPIXELSX)
iDPIY = GetDeviceCaps(hdcRef, LOGPIXELSY)
'Размеры в сотых долях миллиметра
rc.Right = SrcPic.Width '= bm.bmWidth * 2540 / iDPIX
rc.Bottom = SrcPic.Height '= bm.bmHeight * 2540 / iDPIY
'Создаём "усовершенствованный" метафайл в памяти
hdcMeta = CreateEnhMetaFile(hdcRef, vbNullString, rc, vbNullString)
If hdcMeta = 0 Then
ReleaseDC hwndParent, hdcRef
Exit Function
End If
Dim iWEX As Long, iWEY As Long
Dim iVEX As Long, iVEY As Long
Dim iGCD As Long
iWEX = bm.bmWidth * iWidthMM * iDPIX * 10
iWEY = bm.bmHeight * iHeightMM * iDPIY * 10
iVEX = bm.bmWidth * iWidthPels * 254
iVEY = bm.bmHeight * iHeightPels * 254
iGCD = GCD(GCD(GCD(iWEX, iWEY), iVEX), iVEY)
SetMapMode hdcMeta, MM_ANISOTROPIC
SetWindowExtEx hdcMeta, iWEX \ iGCD, iWEY \ iGCD, ByVal 0&
SetViewportExtEx hdcMeta, iVEX \ iGCD, iVEY \ iGCD, ByVal 0&
'Access с целью совместимости с Win9x использует режим STRETCH_DELETESCANS,
'он быстрее, но менее качественный, чем STRETCH_HALFTONE. Последний доступен
'в NT/200x/XP.
Select Case m_pqQuality
'Case pqLow:
Case pqMedium:
SetStretchBltMode hdcMeta, STRETCH_DELETESCANS
Case pqHigh:
SetStretchBltMode hdcMeta, STRETCH_HALFTONE
End Select
hdcMem = CreateCompatibleDC(hdcRef)
hbmpOld = SelectObject(hdcMem, SrcPic.Handle)
BitBlt hdcMeta, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY
SelectObject hdcMem, hbmpOld
DeleteDC hdcMem
ReleaseDC hwndParent, hdcRef
If ReleasePicRef Then Set SrcPic = Nothing 'освобождаем память
hEMF = CloseEnhMetaFile(hdcMeta)
If hEMF = 0 Then Exit Function
m_hEMF = hEMF
Case OBJ_ENHMETAFILE:
hEMF = SrcPic.Handle
'Флаг ReleasePicRef намеренно игнорируем
Case Else:
Exit Function
End Select
cbSize = GetEnhMetaFileBits(hEMF, 0, ByVal 0&)
ReDim bPicData(0 To cbSize + 7) As Byte
PutPicDataLong bPicData, 0, CF_ENHMETAFILE
PutPicDataLong bPicData, 4, hEMF
cbCopied = GetEnhMetaFileBits(hEMF, cbSize, bPicData(8))
Image.PictureData = bPicData
Erase bPicData 'освобождаем память
LoadFromIPicture = True
End Function
Private Function ParentForm(ByVal Ctl As control) As Form
Dim oParent As Object
Set oParent = Ctl
On Error Resume Next
Do
Set oParent = oParent.Parent
Loop Until (Err <> 0) Or (TypeOf oParent Is Form)
Set ParentForm = oParent
End Function
Private Function GCD(ByVal a As Long, ByVal b As Long) As Long
Do While (a <> 0) And (b <> 0)
If a >= b Then a = a Mod b Else b = b Mod a
Loop
GCD = a + b
End Function
Private Sub PutPicDataLong(bData() As Byte, nPos As Long, ByVal lValue As Long)
Dim L As TLong
Dim QB As TQuadBytes
L.lLong = lValue
LSet QB = L
bData(nPos + 0) = QB.bByte(0)
bData(nPos + 1) = QB.bByte(1)
bData(nPos + 2) = QB.bByte(2)
bData(nPos + 3) = QB.bByte(3)
nPos = nPos + 4
End Sub
и модуль
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42.
Option Compare Database
Option Explicit
Private Enum BOOL
FALSE_BOOL = 0&
TRUE_BOOL = 1&
End Enum
Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
Private Declare Function CreateStreamOnHGlobal Lib "ole32" ( _
hGlobal As Any, ByVal fDeleteOnRelease As BOOL, _
Stream As IUnknown) As Long
Private Declare Function OleLoadPicture Lib "olepro32" ( _
ByVal pStream As IUnknown, ByVal lSize As Long, _
ByVal fRunmode As BOOL, riid As GUID, ppvPic As IPictureDisp) As Long
Private Const S_OK As Long = 0&
Public Function LoadPictureUsingStream(bPicData() As Byte) As IPictureDisp
Dim lResult As Long
Dim oStream As IUnknown
Dim IID_IDispatch As GUID
lResult = CreateStreamOnHGlobal(bPicData(LBound(bPicData)), FALSE_BOOL, _
oStream)
If lResult <> S_OK Then Exit Function
With IID_IDispatch
.Data1 = &H20400
.Data4(0) = &HC0
.Data4(7) = &H46
End With
lResult = OleLoadPicture(oStream, UBound(bPicData) - LBound(bPicData) + 1, _
TRUE_BOOL, IID_IDispatch, LoadPictureUsingStream)
End Function
Ими пользовался в 32 бит системе. Однако стал вопрос, отобразить данные ole (а именно изображение) на форме в 64 битной системе.
Есть у кого-нибудь подобное для 64 битной системы?
Заранее благодарен.
|