I need to allow the user to select an icon, so I've implemented the PickIconDlg function from shell32. The problem is that if the user selects a path that is longer than the initial path I declare, the resultant value is the user-selected path truncated to length of the initial path.
For instance, if I set the initial path to "C:\Windows\System32\shell32.dll" and the user selects "C:\Users\Public\Documents\TheIcons\Library.dll", the updated string value comes back as "C:\Users\Public\Documents\TheIc" (i.e. the first 31 characters of the user-selected path, because the initial path is 31 characters long).
I have tried adjusting the 'nMaxFile' value I pass to PickIconDlg, which I understand is supposed to set the max length of the path variable. This doesn't seem to make a difference.
Declare Unicode Function PickIconDlg Lib "Shell32" Alias "PickIconDlg" (ByVal hwndOwner As IntPtr, ByVal lpstrFile As String, ByVal nMaxFile As Integer, ByRef lpdwIconIndex As Integer) As Integer
Public Function GetIconLoc(frmform As Form) As Object()
Dim iconfile As String = Environment.GetFolderPath(Environment.SpecialFolder.System) + "\shell32.dll"
Dim iconindex As Integer ' Will store the index of the selected icon
If PickIconDlg(frmform.Handle, iconfile, 50, iconindex) = 1 Then
MessageBox.Show(iconfile)
Return {iconfile, iconindex}
Else
Return Nothing
End If
End Function
I expect the string variable iconfile to contain the full user-selected path, as its length is less than the defined max of 50 characters. Instead, only a portion of the path is returned, as described above.
Append a Null character plus empty space after the original file name to create a string buffer large enough to contain the result.
Dim iconfile As String = _
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "shell32.dll") & _
vbNullChar & Space(256)
Then pass the total length when calling the function
PickIconDlg(frmform.Handle, iconfile, Len(iconfile), iconindex)
And finally cut the extra space from the result
iconfile = Left(iconfile, InStr(iconfile, vbNullChar) - 1)
Also, use Path.Combine
instead of concatenating the path yourself. Path.Combine
adds missing or removes extra backslashes (\
) automatically.