Office中國論壇/Access中國論壇

標題: 用代碼插入圖片到OLE對象的2種方法 [打印本頁]

作者: t小寶    時間: 2013-7-26 17:42
標題: 用代碼插入圖片到OLE對象的2種方法
Access中的Ole對象總感覺是個神秘的東西,功能好象很強大,既可以顯示圖片,還可顯示Word文檔、Excel表格等,但對它的控制卻不象其它對象那么容易,聯機幫助中講的不多,僅有的一點幫助看得也是一頭霧水。
拿Ole字段儲存圖片來說,通過菜單操作在Ole字段中插入圖片后,在表中會以文字顯示,可能是“圖片”,又可能是“位圖圖像”,還可能是“包”,綁定到窗體的Ole對象框后,有的顯示圖片,有的是顯示一個圖標加上文件名?傊鞣N情況,有點讓人望而卻步,玩不起不玩總可以吧~

不過有時候我們還不得不用它,比如要在連續(xù)窗體每一行顯示一個圖片時,就可以用ole字段來顯示圖片了。紅塵如煙大俠大家都知道吧,他做的通用平臺里的圖標編輯窗口就是這樣的。

那么怎樣在ole字段中插入圖片文件,綁定到窗體時能顯示為圖片?有下面兩個方法:
1、象上面說的用Access自身提供的插入對象操作,插入圖片文件,但只有位圖文件能顯示圖片。
2、把圖片插入到Access的圖片框中,再復制圖片框粘貼到ole對象框,或者把圖片插入到Word中,再把Word中的圖片復制粘貼到ole對象框。這種方法可以顯示大部分格式的圖片,jpg、gif、png、ico等都可以,并且還可以保持透明哦~

這些大家可能都懂了,我只是總結一下,呵呵...

但是,昨天嶺南王子給我下任務了,說要用純代碼插入圖片到ole對象框...王子的命令不得不執(zhí)行啊...
不過王子的要求很合理,封裝好的程序給別人使用,要添加圖片,總不能讓人打開Word把圖片拷來拷去吧,顯示得太不專業(yè)了。

今天把上面說的兩種手工插入圖片的方法用代碼實現了,把關鍵的第二種貼上來,做得匆忙請大家指正:
模塊中:
  1. ' 示  例: 演示代碼插入圖片到Ole對象框的2種方法
  2. ' 作  者: t小寶(QQ:377922812)
  3. ' 日  期: 2013-07-26

  4. Private Type METAFILEPICT
  5.         mm As Long
  6.         hMF As Long
  7.         yExt As Long
  8.         xExt As Long
  9. End Type

  10. Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)

  11. Private Declare Function SetEnhMetaFileBits Lib "gdi32" (ByVal cbBuffer As Long, lpData As Byte) As Long
  12. Private Declare Function SetMetaFileBitsEx Lib "gdi32" (ByVal nSize As Long, lpData As Byte) As Long
  13. Private Declare Function SetWinMetaFileBits Lib "gdi32" (ByVal cbBuffer As Long, lpbBuffer As Byte, ByVal hdcRef As Long, lpmfp As METAFILEPICT) As Long

  14. Private Declare Function GlobalAlloc Lib "kernel32.dll" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
  15. Private Declare Function GlobalLock Lib "kernel32.dll" (ByVal hMem As Long) As Long
  16. Private Declare Function GlobalSize Lib "kernel32.dll" (ByVal hMem As Long) As Long
  17. Private Declare Function GlobalUnlock Lib "kernel32.dll" (ByVal hMem As Long) As Long
  18. Private Declare Function GlobalFree Lib "kernel32.dll" (ByVal hMem As Long) As Long

  19. Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
  20. Private Declare Function CloseClipboard Lib "user32" () As Long
  21. Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
  22. Private Declare Function SetClipboardData Lib "user32" (ByVal wFormat As Long, ByVal hMem As Long) As Long
  23. Private Declare Function EmptyClipboard Lib "user32" () As Long

  24. Private Const CF_BITMAP = 2
  25. Private Const CF_DIB = 8
  26. Private Const CF_METAFILEPICT = 3
  27. Private Const CF_ENHMETAFILE = 14
  28. Private Const GMEM_MOVEABLE = &H2

  29. '----------------------------------------------------------------------------------------------------------------------------------
  30. ' 代碼插入圖片到Ole對象框之剪貼板法
  31. ' 原理:先加載圖片到圖片框,獲取圖片框的PictureData,根據其類型轉為相應格式放到剪貼板,最后粘貼到Ole對象框。
  32. ' 這個方法相當于在設計視圖中插入一幅圖片到圖片框,然后復制該圖片框,再在窗體視圖中粘貼到Ole對象框。
  33. ' 這種方法支持更多的格式,只要能加載到圖片框的圖片都可以插入到Ole對象框中并顯示。
  34. ' 但透明的png圖片會有鋸齒,這沒辦法。因為Ole對象框只能顯示位圖和圖元文件,增強型圖元文件粘貼到Ole對象框中會轉為圖元文件。
  35. ' 另外,圖片框能加載的圖片格式及效果和電腦上安裝的圖形篩選器版本有關。
  36. ' 注意:對于2007或以上版本,須要在Access選項中將圖片屬性儲存格式設置為:將所有圖片數據轉換成位圖。否則使用此方法不成功。
  37. ' 也可用LoadPicture直接創(chuàng)建StdPicture對象來獲取圖像的句柄并處理,但不支持png圖片,且gif圖片也會丟失透明部分,非透明圖片可用。
  38. '----------------------------------------------------------------------------------------------------------------------------------
  39. Public Function ImageToObjFrame(imgBox As Image, objFrame As BoundObjectFrame) As Boolean
  40. On Error GoTo ErrHandle

  41.     Dim bytArray() As Byte
  42.     Dim tMf As METAFILEPICT
  43.     Dim hGlobal As Long
  44.     Dim lHandle As Long
  45.     Dim lRet As Long

  46.     If IsNull(imgBox.PictureData) Then Exit Function

  47.     If OpenClipboard(0) Then                                                      ' 使用剪貼板前先打開
  48.         Call EmptyClipboard                                                       ' 為了不出意外清空剪貼板給自己用
  49.         bytArray() = imgBox.PictureData                                           ' 把圖片框的數據放到數組備用

  50.         Select Case bytArray(0)                                                   ' 圖片框中的圖片有位圖、圖元文件、增強圖元文件3種類型
  51.         Case 40  '位圖(DIB)
  52.             hGlobal = GlobalAlloc(GMEM_MOVEABLE, UBound(bytArray) + 1)            ' 創(chuàng)建緩沖區(qū),用于存放DIB數據
  53.             lHandle = GlobalLock(hGlobal)                                         ' 獲取緩沖區(qū)讀寫指針,這個指針就是DIB的句柄了
  54.             CopyMemory ByVal lHandle, bytArray(0), UBound(bytArray) + 1           ' 復制字節(jié)數組內容(DIB數據)到緩沖區(qū)
  55.             GlobalUnlock hGlobal                                                  ' 解鎖后才能使用
  56.             lRet = SetClipboardData(CF_DIB, lHandle)                              ' 把DIB放入剪貼板
  57.             GlobalFree hGlobal                                                    ' 釋放分配的緩沖區(qū)空間,也可以不釋放,系統(tǒng)會自己處理
  58.             
  59.         Case 3   '圖元文件
  60. '            lHandle = SetMetaFileBitsEx(UBound(bytArray) + 1 - 24, bytArray(24))               ' 創(chuàng)建圖元文件
  61. '            lRet = SetClipboardData(CF_METAFILEPICT, lHandle)                                  ' 把圖元文件放入剪貼板,不成功,不知何故!

  62.             '上面的代碼把圖元文件放入剪貼板不成功,轉成增強型圖元文件就可以了
  63.             CopyMemory tMf, bytArray(8), Len(tMf)
  64.             lHandle = SetWinMetaFileBits(UBound(bytArray) + 24 + 1 - 8, bytArray(24), 0&, tMf)   ' 從圖元文件數據創(chuàng)建增強型圖元文件
  65.             lRet = SetClipboardData(CF_ENHMETAFILE, lHandle)                                     ' 把增強型圖元文件放入剪貼板

  66.         Case 14  '增強圖元文件
  67.             lHandle = SetEnhMetaFileBits(UBound(bytArray) + 1 - 8, bytArray(8))                  ' 創(chuàng)建增強型圖元文件
  68.             lRet = SetClipboardData(CF_ENHMETAFILE, lHandle)                                     ' 把增強型圖元文件放入剪貼板
  69.         Case Else
  70.         End Select
  71.         
  72.         Call CloseClipboard                                                       ' 必須關閉剪貼板才能復制
  73.         
  74.         If lRet Then
  75.             objFrame.SetFocus                                                     ' 把焦點移到Ole對象框
  76.             DoCmd.RunCommand acCmdPaste                                           ' 把上面放到剪貼板中的東東粘貼到Ole對象框中
  77.             Call OpenClipboard(0)                                                 ' 重新打開剪貼板以清空內容。也可以保留
  78.             Call EmptyClipboard                                                   ' 清空剪貼板
  79.             Call CloseClipboard                                                   ' 剪貼板用完要關閉,不然之后程序不能正常復制
  80.             ImageToObjFrame = True
  81.         End If

  82.     End If
  83. ErrHandle:
  84.    
  85. End Function
復制代碼
窗體中:
  1. '----------------------------------------------------------------------------------------------------------------------------------
  2. ' 代碼插入圖片到Ole對象框之剪貼板法
  3. ' 原理:請看模塊中的ImageToObjFrame函數
  4. '----------------------------------------------------------------------------------------------------------------------------------
  5. Private Sub Command2_Click()

  6.     Dim sFileName As String
  7.     Dim bytArray() As Byte
  8.     Dim tMf As METAFILEPICT
  9.     Dim hGlobal As Long
  10.     Dim lHandle As Long
  11.     Dim lRet As Long

  12.     sFileName = GetFileName(1, , "圖片文件(*.bmp;*.jpg;*.gif;*.ico;*.tif;*.png;*.wmf;*.emf)BMP格式(*.bmp)JPG格式(*.jpg)GIF格式(*.gif)ICO格式(*.ico)TIFF格式(*.tif)PNG格式(*.png)WMF格式(*.wmf)EMF格式(*.emf)")
  13.     If Len(sFileName) = 0 Then Exit Sub

  14.     Me.Image0.Picture = sFileName
  15.    
  16.     If ImageToObjFrame(Me.Image0, Me.FPicture2) Then
  17.         Me.FName = Mid(sFileName, InStrRev(sFileName, "") + 1)
  18.     End If
  19.    
  20.     Me.Image0.Picture = ""
  21.    
  22. End Sub
復制代碼
示例mdb是少不了的:





作者: t小寶    時間: 2013-7-26 17:47
坐個沙發(fā)
有圖有真相,兩種方法效果對比
[attach]52226[/attach]

作者: 嶺南王子    時間: 2013-7-26 17:58
謝謝分享!

作者: smileyoufu    時間: 2013-7-26 18:06
好東西,板凳一個。
作者: xie62    時間: 2013-7-26 18:23
謝謝分享!

作者: tmtony    時間: 2013-7-26 22:34
精彩, 謝謝小寶分享!
作者: tmtony    時間: 2013-7-26 22:35
轉播一下
作者: zhuyiwen    時間: 2013-7-27 05:52
頂一個,呵呵
作者: asklove    時間: 2013-7-29 16:16
收藏了,謝分享
作者: kangking    時間: 2013-8-26 10:39
學習
作者: yanwei82123300    時間: 2013-8-26 15:14
謝謝分享1!小寶老師真棒!
作者: wang1950317    時間: 2013-8-28 21:15
正好用的上,謝謝小寶大師!
作者: yedaoan    時間: 2013-9-12 11:09
好東西,就是一直在找的
作者: 輕風    時間: 2013-9-12 11:52
精彩
作者: yedaoan    時間: 2013-9-15 13:10
t小寶,測試了你的大作,發(fā)現一個問題,用方法2添加bmp,馬上崩潰,其他圖片格式沒有問題,最近在用你的這個示列,但是我找不出問題在那里?
作者: yedaoan    時間: 2013-9-15 13:14
剛才又試了一下,不是所有的BMP格式圖片都有問題,我這里有幾張有問題(這個圖片的來源是通過屏幕截圖過來的),我發(fā)上來,你們研究一下
作者: efcndi    時間: 2013-9-16 14:38
看看
作者: zhao__feng    時間: 2013-9-20 21:36
謝謝分享!
作者: wuheng    時間: 2013-9-29 17:22
學習呀~~~~~```
作者: 大懶貓68    時間: 2013-10-3 14:59
好東西,板凳一個
作者: fcghw    時間: 2013-10-11 02:53
還是看不懂啊
作者: fcghw    時間: 2013-10-11 02:54
還是看不懂了
作者: 程研    時間: 2013-10-11 11:41

作者: XB2009    時間: 2013-11-13 16:29
看看
作者: 好運牛    時間: 2013-11-13 17:37
謝謝t小寶 大師的分享
作者: 好運牛    時間: 2013-11-13 17:48
非常感謝大師的指導

作者: sxb2007    時間: 2013-11-15 11:35
謝謝分享!
作者: 好運牛    時間: 2013-11-17 10:40
學做了實例,很有收獲。頂
作者: 13601812106_01    時間: 2013-12-4 12:31
好好好

作者: leonshi    時間: 2014-1-8 08:46
學習

作者: justic    時間: 2014-2-8 10:33
正是我所需的
作者: louislee    時間: 2014-4-25 19:19
ding
作者: xiaowuo2    時間: 2014-4-25 20:05
看看效果如何,頂個
作者: lzh199    時間: 2014-5-16 13:50
學習學習啊
作者: zcg13051    時間: 2014-5-16 17:19
回復看看學習學習
作者: shuyangchao    時間: 2014-5-16 23:13
學習
作者: 小橋人家    時間: 2014-5-30 20:36
學習學習
作者: yjlchen    時間: 2014-5-30 21:49
謝謝分享
作者: lancet    時間: 2014-6-6 07:43
Thanks,that's my looking for
作者: layaman_999    時間: 2014-6-11 12:08
非常精彩,受教了
作者: ilikeu    時間: 2014-6-13 10:51
下來看看
作者: zpy2    時間: 2014-6-19 07:14
學習了。!
作者: wx0000888    時間: 2014-9-6 16:33
真有這種方法,謝謝
作者: liumporite    時間: 2014-9-24 14:38
DDDDDDDDDDDDDDDDDDDDDDDD
作者: yanghua1900363    時間: 2014-9-24 22:48
謝謝分享必須的
作者: th2328646    時間: 2014-10-14 14:06
sdfsf
作者: znbcaozhiming    時間: 2014-10-17 00:30
初學,正好可以學習下
作者: sunwrsun    時間: 2014-10-29 22:09
看看
作者: herry2003aa    時間: 2014-10-31 01:11
查看事例是少不了的。
作者: dhlhmgc    時間: 2014-11-11 02:42
學習了,對OLE的處理不熟,感謝分享
作者: LiYuanqi    時間: 2014-12-16 19:50
謝謝樓主分享
作者: zxclen    時間: 2014-12-19 17:17

作者: lee2099    時間: 2015-1-13 09:31
有圖有真相,兩種方法效果對比

作者: 天涯淪落20131    時間: 2015-1-14 11:11
000000
作者: zhhporsche    時間: 2015-1-20 09:36
此貼不錯,正是我所需要的,贊一個
作者: 水滴的邂逅    時間: 2015-1-21 16:03
learning how to do it
作者: 站到終點站    時間: 2015-2-6 21:54
學習了
作者: pstoto    時間: 2015-3-31 00:20
感謝分享技術
作者: 老榕樹下    時間: 2015-5-23 15:09
找了好久,終于找到了
作者: ppppn    時間: 2015-5-31 16:41
學習
作者: 205226    時間: 2015-6-25 14:48
學習。!
作者: YXH_YXH    時間: 2015-7-31 10:42
多謝分享。。。。。。!
作者: 讀書人2015    時間: 2015-7-31 22:45
這要好好看看
作者: huangqinyong    時間: 2015-8-13 16:18
好好學習一下
作者: ligand    時間: 2015-9-21 18:15
很棒。好好學習一下
作者: 魔天天自在    時間: 2015-10-24 22:56
學習了 太高深了
作者: 三毛流浪記    時間: 2015-10-25 18:00
666
作者: zhoubo780624    時間: 2015-12-7 02:08
學習 一下
作者: Joshui    時間: 2015-12-12 23:42
xuexie ~
作者: dmvpey    時間: 2015-12-22 19:31
1,建議樓主自己發(fā)帖的時候粘貼個圖片效果出來
2,是否能支持縮放?
作者: xlb004    時間: 2016-1-7 19:00
1111111111111111111111111111111111
作者: jxlt    時間: 2016-1-10 11:34
測試一下。。。
作者: alphalau81    時間: 2016-2-25 16:37
看看O(∩_∩)O哈哈哈~
作者: spirityq    時間: 2016-2-26 16:36
找這個實例真的找了好久呀!
作者: 玉樹TMD臨風    時間: 2016-2-27 20:36
怎么這么麻煩的。
作者: 玉樹TMD臨風    時間: 2016-2-27 20:41
下載測試了一下都沒成功,特別是方法二一試就停止響應。我的圖片已經設置為將所有圖片數據轉換成位圖,加載ICO、JPG和BMP都報錯。
作者: hunrybecky    時間: 2016-2-28 01:35
正需要這個例子,找了很久
作者: yphxsjjlcq    時間: 2016-3-2 00:19
謝謝分享!
作者: shindo8888    時間: 2016-3-10 13:58
關注,學習中
作者: v1453213087    時間: 2016-3-10 16:32
看看

作者: leolifk    時間: 2016-3-14 14:50
感謝樓主,好好學習,天天向上
作者: baidu321    時間: 2016-3-15 10:15
哇  這個有用,想問下樓主,這個方法像占用數據庫多大空間???
作者: guowj_sqi    時間: 2016-3-19 14:55
謝謝樓主分享!
作者: 雪山一支蒿    時間: 2016-3-26 20:53
學習學習
作者: csxt    時間: 2016-3-31 21:08
正是我想要的下來看看
作者: aslxt    時間: 2016-4-1 17:29
學習學習
作者: pwj2009    時間: 2016-4-5 23:56
感謝分享!
作者: newglord    時間: 2016-4-7 16:10
回復好下載
作者: jianghu1    時間: 2016-4-7 17:39
下載來看看
作者: cityguy    時間: 2016-4-25 15:44

謝謝分享!!
作者: zhujie666    時間: 2016-4-28 10:09
真的是個好東西啊
作者: JohnYao    時間: 2016-5-31 12:13
對于小公司用作記錄數據庫文件當中的圖片來說,真的很方便。
作者: wx0000888    時間: 2016-6-27 12:16
經過測試:

ACCESS2000版的  jpg格式的可以通過     bytArray(0-3591)    bytArray(0) =14
ACCESS2010版的  jpg格式的不能通過     bytArray(0-1405)    bytArray(0) =0   ,其他格式也不行.
作者: 唐金龍    時間: 2016-7-8 16:49
看一看學習一下.
作者: p51219    時間: 2016-7-10 00:13
好好好紅啊紅啊后
作者: COMEON    時間: 2016-7-20 16:52
this is what i want. thanks!

作者: jicheng    時間: 2016-8-17 14:26
學習
作者: MYDAAN    時間: 2016-9-5 21:00
好久沒回來了,學習一下
作者: Dozen    時間: 2016-9-16 15:08
一大段代碼,嚇死人了。。。
作者: 飛鴻    時間: 2016-11-9 13:33
大大大大大大大大大大大大大




歡迎光臨 Office中國論壇/Access中國論壇 (http://www.mzhfr.cn/) Powered by Discuz! X3.3