Как исправить ошибку для 64-разрядного VBA PPT, преобразованного из 32-разрядного - PullRequest
0 голосов
/ 11 ноября 2018

Эта программа VBA работала для 32-битного PPT 2007, но когда я использовал ее для 64-битного PPT 2013, была ошибка, даже когда я добавил PtrSafe перед Public Declare.

Произошло совпадение типов в этой функции: AddressOf BrowseCallbackProc (в середине публичной функции Get_IMGFolderName())

Я хотел бы получить совет о том, как решить эту проблему. Я занимаюсь программированием как хобби, поэтому я мало что знаю.

Thankyou

Option Explicit

Public Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
Public Declare PtrSafe Function SHBrowseForFolder Lib "shell32" (lpbi As BrowseInfo) As Long
Public Declare PtrSafe Function SHGetPathFromIDList Lib "shell32" (ByVal pidList As Long, ByVal lpBuffer As String) As Long
Public Declare PtrSafe Function lstrcat Lib "kernel32" Alias "lstrcatA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long

Public Type BrowseInfo
    hwndOwner       As Long
    pIDLRoot        As Long
    pszDisplayName  As Long
    lpszstrMsg      As Long
    ulFlags         As Long
    lpfnCallback    As Long
    lParam          As Long
    iImage          As Long
End Type

Public Const BIF_STATUSTEXT = &H4&
Public Const BIF_RETURNONLYFSDIRS = 1
Public Const BIF_DONTGOBELOWDOMAIN = 2
Public Const MAX_PATH = 260
Public Const WM_USER = &H400
Public Const BFFM_INITIALIZED = 1
Public Const BFFM_SELCHANGED = 2
Public Const BFFM_SETSTATUSTEXT = (WM_USER + 100)
Public Const BFFM_SETSELECTION = (WM_USER + 102)

Public strCurDir As String   '현재 디렉토리

  Public Enum CHOOSE_COLOR_FLAGS
    CC_RGBINIT = &H1&
    CC_FULLOPEN = &H2&
    CC_PREVENTFULLOPEN = &H4&
    CC_SHOWHELP = &H8&
    CC_ENABLEHOOK = &H10&
    CC_ENABLETEMPLATE = &H20&
    CC_ENABLETEMPLATEHANDLE = &H40&
    CC_SOLIDCOLOR = &H80&
    CC_ANYCOLOR = &H100&
  End Enum

  Private Type CHOOSECOLOR
    lStructSize As Long
    hwndOwner As Long
    hInstance As Long
    rgbResult As Long
    lpCustColors As Long
    flags As CHOOSE_COLOR_FLAGS
    lCustData As Long
    lpfnHook As Long
    lpTemplateName As String
  End Type

  Private Declare PtrSafe Function ChooseColor_API Lib "comdlg32.dll" Alias "ChooseColorA" (lpChoosecolor As CHOOSECOLOR) As Long



Function Delete_Sheets()

'ActiveWindow.View.GotoSlide ActivePresentation.Slides.Count
While ActivePresentation.Slides.Count > 0
    ActiveWindow.Selection.SlideRange.Delete
Wend

End Function



Public Function Get_IMGFolderName() As String

Dim lpIDList As Long
Dim szstrMsg As String
Dim strBuffer As String
Dim tBrowseInfo As BrowseInfo
Dim strDir As String

strCurDir = frmBible.lblIMGFolder.Caption & vbNullChar

szstrMsg = "바탕그림용 이미지가 들어 있는 폴더를 지정해주세요"
With tBrowseInfo
    .hwndOwner = 0
    .lpszstrMsg = lstrcat(szstrMsg, "")
    .ulFlags = BIF_RETURNONLYFSDIRS + BIF_DONTGOBELOWDOMAIN + BIF_STATUSTEXT
    .lpfnCallback = GetAddressofFunction(AddressOf BrowseCallbackProc)  'get address of function.
End With

lpIDList = SHBrowseForFolder(tBrowseInfo)
If (lpIDList) Then
    strBuffer = Space(MAX_PATH)
    SHGetPathFromIDList lpIDList, strBuffer
    strBuffer = Left(strBuffer, InStr(strBuffer, vbNullChar) - 1)
    Get_IMGFolderName = strBuffer
Else
    Get_IMGFolderName = ""
End If

End Function



Public Function Remove_Special_Chars(intxt) As String

Dim wkstr As String
Dim p As Integer, c, uc

wkstr = ""
While Len(intxt) > 0
    c = Left(intxt, 1)
    uc = UCase(c)
    If c >= "가" And c <= "힝" Then
        wkstr = wkstr & c
    ElseIf uc >= "A" And uc <= "Z" Then
        wkstr = wkstr & c
    ElseIf uc >= "0" And uc <= "9" Then
        wkstr = wkstr & c
    End If
    intxt = Mid(intxt, 2)
Wend

Remove_Special_Chars = wkstr

End Function




Public Function Return_PathName(full_Path As String)

'return path name only

Dim p As Integer, ps As Integer

ps = 1
p = 1
Do While p > 0
    p = InStr(ps, full_Path, "\", vbBinaryCompare)
    If p > 0 Then
        ps = p + 1
    End If
Loop

Return_PathName = Left(full_Path, ps - 1)

End Function

Public Function Return_FileName(full_Path As String)

' return file name only

Dim p As Integer, ps As Integer

ps = 1
p = 1
Do While p > 0
    p = InStr(ps, full_Path, "\", vbBinaryCompare)
    If p > 0 Then
        ps = p + 1
    End If
Loop

Return_FileName = Mid(full_Path, ps)

End Function

Public Function Return_FolderName(full_Path)

' return folder name only

Dim p As Integer

p = InStrRev(full_Path, "\", Len(full_Path) - 1)

Return_FolderName = Mid(full_Path, p + 1)

End Function





Public Function BrowseCallbackProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal lp As Long, ByVal pData As Long) As Long
Dim lpIDList As Long
Dim lngRet As Long
Dim strBuffer As String

On Error Resume Next

Select Case uMsg

    Case BFFM_INITIALIZED
        Call SendMessage(hWnd, BFFM_SETSELECTION, 1, strCurDir)

    Case BFFM_SELCHANGED
        strBuffer = Space(MAX_PATH)

        lngRet = SHGetPathFromIDList(lp, strBuffer)
    If lngRet = 1 Then
        Call SendMessage(hWnd, BFFM_SETSTATUSTEXT, 0, strBuffer)
    End If

End Select
On Error GoTo 0

BrowseCallbackProc = 0

End Function



Public Function GetAddressofFunction(lngAdd As Long) As Long

GetAddressofFunction = lngAdd

End Function


Public Function FileDateInfo(filespec)
    Dim fs, f
    Set fs = CreateObject("Scripting.FileSystemObject")
    Set f = fs.GetFile(filespec)
    FileDateInfo = f.DateLastModified

End Function


Public Function WinRegistry_CommonGet()

Dim TmpName As String
Dim i As Integer
Dim x

Version_Release = GetSetting("BibleChoir", "LatestVal", "Version_Release", "vv.rr")


frmBible.lblIMGFolder.Caption = GetSetting("BibleChoir", "LatestVal", "IMGFolder", "없음")
'frmPicture.sldBright = GetSetting(appname:="BibleChoir", section:="LatestVal", key:="Bright", Default:=70)
frmBible.chkEachPage = GetSetting("BibleChoir", "LatestVal", "EachPage", False)

 File2Open = frmBible.lblIMGFolder.Caption


 If File2Open <> "없음" Then
  On Error Resume Next
 frmBible.ImgPreview.Picture = LoadPicture(File2Open)
 End If
 On Error GoTo 0
End Function

Public Function WinRegistry_CommonSave()

Dim i As Integer

SaveSetting "BibleChoir", "LatestVal", "Version_Release", Version_Release

SaveSetting "BibleChoir", "LatestVal", "IMGFolder", frmBible.lblIMGFolder.Caption
'SaveSetting "BibleChoir", "LatestVal", "Bright", frmPicture.sldBright
SaveSetting "BibleChoir", "LatestVal", "EachPage", frmBible.chkEachPage


End Function

1 Ответ

0 голосов
/ 11 ноября 2018

Вам нужно сделать больше, чем просто добавить объявление PtrSafe. Некоторые из ваших Long типов данных также необходимо преобразовать в LongPtr.

#If VBA7 Then

    Public Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" _
            (ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, _
            ByVal lParam As String) As LongPtr
    Public Declare PtrSafe Function SHBrowseForFolder Lib "shell32" _
            (lpbi As BrowseInfo) As LongPtr
    Public Declare PtrSafe Function SHGetPathFromIDList Lib "shell32" _
            (ByVal pidList As LongPtr, ByVal lpBuffer As String) As LongPtr
    Public Declare PtrSafe Function lstrcat Lib "kernel32" Alias "lstrcatA" _
            (ByVal lpString1 As String, ByVal lpString2 As String) As Long

#Else

    Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
            (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _
            ByVal lParam As String) As Long
    Public Declare Function SHBrowseForFolder Lib "shell32" _
            (lpbi As BrowseInfo) As Long
    Public Declare Function SHGetPathFromIDList Lib "shell32" _
            (ByVal pidList As Long, ByVal lpBuffer As String) As Long
    Public Declare Function lstrcat Lib "kernel32" Alias "lstrcatA" _
            (ByVal lpString1 As String, ByVal lpString2 As String) As Long

#End If

Из Документы Microsoft :

Примечание Объявление операторов с ключевым словом PtrSafe является рекомендуемым синтаксисом. Объявите операторы, которые включают PtrSafe , корректно работают в среде разработки VBA7 как на 32-битной, так и на 64-битной платформах только после всех типов данных в операторе Declare (параметры и возвращаемые значения), которые необходимость хранения 64-битных величин обновлена ​​для использования LongLong для 64-битных интегралов или LongPtr для указателей и дескрипторов. Для обеспечения обратной совместимости с VBA версии 6 и более ранних версий используйте следующую конструкцию:

#If VBA7 Then 
    Declare PtrSafe Sub... 
#Else 
    Declare Sub... 
#EndIf

При работе в 64-разрядных версиях Office Объявление операторы должны включать ключевое слово PtrSafe . Ключевое слово PtrSafe утверждает, что оператор Declare безопасен для выполнения в 64-разрядных средах разработки. Добавление ключевого слова PtrSafe к оператору Declare означает только то, что оператор Declare явно нацелен на 64-битные, все типы данных в пределах оператора, которые должны хранить 64-битные (включая возвращаемые значения и параметры) ) по-прежнему необходимо изменить для хранения 64-битных величин, используя LongLong для 64-битных интегралов или LongPtr для указателей и дескрипторов.

...