Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

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

ByVal behavior in API acts like ByRef?

Status
Not open for further replies.

TheTick

Mechanical
Mar 5, 2003
10,194
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


[bat]All this machinery making modern music can still be open-hearted.[bat]
 
Replies continue below

Recommended for you

It's a string, so you're only passing the address of the string, not the whole string. The 'lp' in the beginning of the var name indicates that it's a pointer.
 
Actually, that's not true. I did get a solid explanation when I posed this question on tek-tips.com (I hope Mr. Murphy isn't angry about the double-posting).
see
Basically, ByVal will behave like ByRef in Windows API due to differences between how strings are defined in C vs. VB.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor