powered by simpleCommunicator - 2.0.54     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Отображение изображения на форме
5 сообщений из 5, страница 1 из 1
Отображение изображения на форме
    #39332359
Agapov_stas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем доброго времени суток!
Вопрос такого характера.

Есть модудь класса CPictureData
Код: vbnet
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


и модуль
Код: vbnet
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 битной системы?

Заранее благодарен.
...
Рейтинг: 0 / 0
Отображение изображения на форме
    #39332449
MrShin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Перевести самому довольно просто, занимает минут 5 на вызов API в среднем. Приложен список API фунукций для 64 бит. Добавляете условную компиляцию в объявления функций, а также проверяете все вызовы и объявления переменных - везде, где используется LongPtr или LongLong нужно будет также через условную компиляцию добавить новый тип.
...
Рейтинг: 0 / 0
Отображение изображения на форме
    #39332451
guest_rusimport
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Agapov_stas,
вот тут была хорошая статья Joss -a
http://am.rusimport.ru/msaccess/topic.aspx?ID=797
...
Рейтинг: 0 / 0
Отображение изображения на форме
    #39332469
Agapov_stas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MrShin , guest_rusimport , благодарю. Решил вопрос пока немного иначе, без заморочек с битностью системы.
Сохраняю во временный файл и уже из него отображаю в объекте Picture. В принципе пока по скорости ничего не теряется, открывается достаточно быстро, я бы сказал мгновенно.

P.S. MrShin , Не все там так просто с заменой на LongLong и LongPtr. Там нужно смотреть спецификации функций, чтобы знать где конкретно менять(а меняется не везде). Где-то в топике ув. Бенедикт об этом писал. В итоге я промучался с заменой и решил вообще забить на такой подход и выбрал временный файл.
...
Рейтинг: 0 / 0
Отображение изображения на форме
    #39332501
MrShin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Agapov_stasТам нужно смотреть спецификации функций
Конечно нужно, я и упоминал об этом, но в подробностях не расписывал. Именно из-за этого время на каждую функцию не секунды, а может доходить до часов при сложных функциях, в параметрах которых используются новые типы, а данные обрабатываются в VBA коде. У меня, например, ушло больше 2-х часов на добавление 64-х битной совместимости в некоторый аналог того что требуется - вывод и сохранение картинки с веб камеры, хотя там был всего с десяток API вызовов
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Отображение изображения на форме
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]