【问题标题】:MS Access 2019 (64 bit) on windows 10 (64 bit) crashes when calling the GDIP GetImageGraphicsContext or GdipCreateHBITMAPFromBitmap function调用 GDIP GetImageGraphicsContext 或 GdipCreateHBITMAPFromBitmap 函数时,Windows 10(64 位)上的 MS Access 2019(64 位)崩溃
【发布时间】:2018-12-20 15:49:55
【问题描述】:

在调用 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 函数时访问也会崩溃...

似乎存在系统性问题...

【问题讨论】:

    标签: vba ms-access graphics 64-bit gdi+


    【解决方案1】:

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

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

    据我所知,Graph 和 bitmap 是这些函数中使用的唯一指针,因此在存储和传递它们时需要使用 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
    

    【讨论】:

    • 我将声明改为:
    • 嗨 Erik 非常感谢,我将声明更改为 Dim lGraph As LongPtr Private Declare PtrSafe Function GdipGetImageGraphicsContext Lib "gdiplus" (ByVal Image As LongPtr, graphics As LongPtr) As Long --> 我得到一个编译locRet = GdipGetImageGraphicsContext(lBitmap2, lGraph) 的错误编译器提到 lGraph 参数与 byRef 不兼容?最好的问候丹尼尔
    • 哦,那可能是正确的。如果是这种情况,您只需要使用ByVal,并传递VarPtr(graphics) 而不是graphics。
    • 嗯..我尝试了ByVal和VarPtr,将图形变量的类型更改为Object,StdPicture,aso ...->没办法..:-(
    • 嗯?将其更改为对象?这是不对的,它应该保持原样。 ByVal VarPtr(Something) 在外部 API 调用中等于 ByRef Something,无需进一步更改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-07
    • 2013-05-01
    • 1970-01-01
    • 2014-12-03
    • 1970-01-01
    • 2017-06-04
    相关资源
    最近更新 更多