首页 > 解决方案 > 调用 GDIP GetImageGraphicsContext 或 GdipCreateHBITMAPFromBitmap 函数时,Windows 10(64 位)上的 MS Access 2019(64 位)崩溃

问题描述

调用 GDIP GetImageGraphicsContext 或 GdipCreateHBITMAPFromBitmap 函数时,Windows 10(64 位)上的 MS Access 2019(64 位)崩溃

    Declaration part______________________
GDIP code from:
'-------------------------------------------------
'    Picture functions using GDIPlus-API (GDIP)   |
'-------------------------------------------------
'    *  Office 2003/2007/2010 version  *          |
'-------------------------------------------------
'   (c) mossSOFT / Sascha Trowitzsch rev. 04/2010 |
'-------------------------------------------------
Option Compare Database
Option Explicit
...Private Enum PixelFormat
    PixelFormat1bppIndexed = &H30101
    PixelFormat4bppIndexed = &H30402
    pixelFormat8bppIndexed = &H30803
    PixelFormat16bppGreyScale = &H101004
    PixelFormat16bppRGB555 = &H21005
    PixelFormat16bppRGB565 = &H21006
    PixelFormat16bppARGB1555 = &H61007
    PixelFormat24bppRGB = &H21808
    PixelFormat32bppRGB = &H22009
    PixelFormat32bppARGB = &H26200A
    PixelFormat32bppPARGB = &HE200B
    PixelFormat48bppRGB = &H10300C
    PixelFormat64bppARGB = &H34400D
    PixelFormat64bppPARGB = &H1C400E
    PixelFormatMax = 15 '&HF
End Enum
...

Dim lGraph As Long
Dim lBitmap2 As Long
Dim lBitmap As Long
...
Private Declare PtrSafe Function GdipCreateBitmapFromScan0 Lib "gdiplus" (ByVal Width As Long, ByVal Height As Long, ByVal stride As Long, ByVal PixelFormat As Long, scan0 As Any, bitmap As Long) As Long
Private Declare PtrSafe Function GdipGetImageGraphicsContext Lib "gdiplus" (ByVal Image As Long, graphics As Long) As Long
...

Private Sub Form_Load()
Dim locRet as Long

InitGDIP '-> appaears to work fine

locRet = GdipCreateBitmapFromScan0(CLng(600), CLng(600), 0&, PixelFormat32bppARGB, ByVal 0&, lBitmap2) ' <- Appears to work fine until here (return value = 0)
locRet = GdipGetImageGraphicsContext(lBitmap2, lGraph)   <- MS ACCESS 2019 crashes

或者

Private Sub Form_Current()
locRet = GdipCreateHBITMAPFromBitmap(lBitmap2, hBitmap, CLng(BackGrndClr)) ' <- MS ACCESS 2019 crashes here

...

我尝试为“lGraph”变量使用不同的数据类型,但由于数据类型不兼容,在更改数据类型时会出现预编译器错误,所以这没有帮助。有人知道如何让它再次工作吗?在 Windows 7(我猜是 64 位)和 MS Access 2016 32 位下,它工作正常,没有任何问题 -> 我现在尝试转移到 W10 64 位和 Access 2019(64 位)。

调用 GdipCreateHBITMAPFromBitmap 函数时访问也会崩溃……</p>

好像是系统问题。。。

标签: vbams-accessgraphics64-bitgdi+

解决方案


如果您希望 API 调用与 64 位兼容,则需要LongPtr在传递指针的任何位置使用。

拍打PtrSafe你的函数实际上不会使指针安全,你需要自己做,那个关键字表明你已经做到了,并且该函数在 64 位中使用是安全的。如果您在未验证您已将所有指针从 更改为 的情况下使用它,LongLongPtr在 64 位应用程序中调用该函数时 VBA 将发生硬崩溃(在极少数情况下,您甚至会破坏其他应用程序的稳定性)。

据我所知,Graphandbitmap是这些函数中唯一使用的指针,因此在存储和传递它们时需要使用 a LongPtr,但我的 GDI 知识有点有限。

Dim lGraph As LongPtr
Dim lBitmap2 As LongPtr
Dim lBitmap As LongPtr
Private Declare PtrSafe Function GdipCreateBitmapFromScan0 Lib "gdiplus" (ByVal Width As Long, ByVal Height As Long, ByVal stride As Long, ByVal PixelFormat As Long, scan0 As Any, bitmap As Long) As Long
Private Declare PtrSafe Function GdipGetImageGraphicsContext Lib "gdiplus" (ByVal Image As LongPtr, graphics As LongPtr) As Long

推荐阅读