Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

ByVal behavior in API acts like ByRef? 1

Status
Not open for further replies.

LiquidSchwarz

Programmer
Joined
Apr 24, 2003
Messages
9
Location
US
I am a little confused by the behavior of ByVal as it applies to declaring API functions. I thought ByVal was supposed to prevent a function from changing the value of an input parameter. However, it seems that this is not true, given the behavior of some API calls that I have cut-and-pasted into my programs.

I don't know why this is so. It has been working fine, so I just believed and let it be. Now I'm overcome with curiosity.

An example is below. This is pasted from MS knowledge base. The function SHGetPathFromIDList uses ByVal, but the function is still able to change the input parameter lpBuffer.

Pasted code below:
Option Explicit

Private Const BIF_RETURNONLYFSDIRS = 1
Private Const BIF_DONTGOBELOWDOMAIN = 2
Private Const MAX_PATH = 260

Private Declare Function SHBrowseForFolder Lib "shell32" _
(lpbi As BrowseInfo) As Long

Private Declare Function SHGetPathFromIDList Lib "shell32" _
(ByVal pidList As Long, _
ByVal lpBuffer As String) As Long


Private Declare Function lstrcat Lib "kernel32" Alias "lstrcatA" _
(ByVal lpString1 As String, ByVal _
lpString2 As String) As Long

Private Type BrowseInfo
hWndOwner As Long
pIDLRoot As Long
pszDisplayName As Long
lpszTitle As Long
ulFlags As Long
lpfnCallback As Long
lParam As Long
iImage As Long
End Type

Private Sub Command1_Click()
'Opens a Treeview control that displays the directories in a computer

Dim lpIDList As Long
Dim sBuffer As String
Dim szTitle As String
Dim tBrowseInfo As BrowseInfo

szTitle = "This is the title"
With tBrowseInfo
.hWndOwner = Me.hWnd
.lpszTitle = lstrcat(szTitle, "")
.ulFlags = BIF_RETURNONLYFSDIRS + BIF_DONTGOBELOWDOMAIN
End With

lpIDList = SHBrowseForFolder(tBrowseInfo)

If (lpIDList) Then
sBuffer = Space(MAX_PATH)
SHGetPathFromIDList lpIDList, sBuffer
sBuffer = Left(sBuffer, InStr(sBuffer, vbNullChar) - 1)
MsgBox sBuffer

End If
End Sub
 
>ByVal was supposed to prevent a function from changing the value of an input parameter

Sadly not quite, but we'll let that slide for the moment. More importantly you've started to discover the joys of passing strings to API functions...so try a quick look at the following thread where I attempt to explain some of the underlying issues: thread222-558844
 
That's some thread! I'm getting that queasy feeling I get when I need to rely on things working in a manner contrary to "as advertised". In the meantime, I will repeatedly mash the "I BELIEVE" button and enjoy the show.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top