该VBA程序适用于32位PPT 2007,但是当我将其用于64位PPT 2013时,即使在PtrSafe
前面添加了Public Declare
,也会出现错误。
此功能中存在类型不匹配的情况:AddressOf BrowseCallbackProc
(在公共职能Get_IMGFolderName()
的中间)
我想要一些有关如何解决此问题的建议。 我一直将其编码为业余爱好,所以我不太了解。
谢谢
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
答案 0 :(得分:3)
您需要做的不仅仅是添加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
注意 推荐使用 PtrSafe 关键字声明语句。仅在 Declare 语句中的所有数据类型(参数和返回值)之后,包含 PtrSafe 的声明语句才能在32位和64位平台上的VBA7开发环境中正常工作),需要存储64位数量的数据将更新为对LongLong使用64位积分,对LongPtr使用指针和句柄。为了确保与VBA版本6和更早版本的向后兼容性,请使用以下结构:
#If VBA7 Then Declare PtrSafe Sub... #Else Declare Sub... #EndIf
在64位版本的Office中运行 Declare 语句必须包含 PtrSafe 关键字。 PtrSafe 关键字断言,在64位开发环境中运行 Declare 语句是安全的。将 PtrSafe 关键字添加到 Declare 语句仅表示Declare语句明确地以64位为目标,该语句中需要存储64位的所有数据类型(包括返回值)和参数)仍然必须修改,以使用LongLong(用于64位积分)或LongPtr(用于指针和句柄)来容纳64位数量。