I have a function that gets a folder by useing the API call.
Problem is, because of MS-Access Call-Back limitation.. i can not specify the default root.
I tried many solutions.. but still unable to get it to show a default root.
any ideas?
right now i get an error in the line "<--- Errors" in the code below
'=========================
==========
==========
==========
==========
==========
'
' MCommon.EventLog
'
' Common helper functions. Taken from MCommon.Bas
'
'=========================
==========
==========
==========
==========
==========
'
' Author: Monte Hansen [monte@killervb.com]
' Dependencies: None.
'
'=========================
==========
==========
==========
==========
==========
'
' == Copyright 1999-2002 by Monte Hansen, All Rights Reserved Worldwide ==
'
' Monte Hansen (The Author) grants a royalty-free right to use, modify, and
' distribute this code (The Code) in compiled form, provided that you agree
' that The Author has no warranty, obligations or liability for The Code.
' You may distribute The Code among peers but may not sell it, or distribute
' it on any electronic or physical media such as floppy diskettes, compact
' disks, bulletin boards, web sites, and the like, without first obtaining
' The Author's consent.
'
' When distributing The Code among peers, it is respectfully requested that
' it be distributed as is, but at no time shall it be distributed without
' the copyright notice hereinabove.
'
'=========================
==========
==========
==========
==========
==========
Option Explicit
'=========================
==========
==========
==========
==========
==========
' Constants
'=========================
==========
==========
==========
==========
==========
Private Const Module As String = "MCommon"
Private Const WM_USER As Long = &H400&
Private Const ERROR_SUCCESS As Long = 0
Private Const INVALID_HANDLE_VALUE As Long = -1
Private Const LOGPIXELSX As Long = 88
Private Const LOGPIXELSY As Long = 90
Private Const MAX_COMPUTERNAME_LENGTH As Long = 15&
Private Const FORMAT_MESSAGE_FROM_SYSTEM
= &H1000&
'=========================
==========
==========
==========
==========
==========
' Enums
'=========================
==========
==========
==========
==========
==========
'Public enum EncodeFormats ' Used by HexEncodeData
' efHexBytes = 0
' efHexWORDS = 1
' efHexDWORDs = 2
' efHexQWORDs = 3
'End Enum
Private Const efHexBytes = 0
Private Const efHexWORDS = 1
Private Const efHexDWORDs = 2
Private Const efHexQWORDs = 3
'Public Enum ShellVirtualFolders ' ShellFolder Browsing
' CSIDL_DESKTOP = &H0 ' Windows desktop - virtual folder at the root of the name space.
' CSIDL_INTERNET = &H1 ' Virtual folder representing the Internet
' CSIDL_PROGRAMS = &H2 ' File system directory that contains the user's program groups (which are also file system directories).
' CSIDL_CONTROLS = &H3 ' Control Panel - virtual folder containing icons for the control panel applications.
' CSIDL_PRINTERS = &H4 ' Printers folder - virtual folder containing installed printers.
' CSIDL_PERSONAL = &H5 ' File system directory that serves as a common respository for documents.
' CSIDL_FAVORITES = &H6 ' Favorite Places - file system folder that stores web (or other) links
' CSIDL_STARTUP = &H7 ' File system directory that corresponds to the user's Startup program group.
' CSIDL_RECENT = &H8 ' File system directory that contains the user's most recently used documents.
' CSIDL_SENDTO = &H9 ' File system directory that contains Send To menu items.
' CSIDL_BITBUCKET = &HA ' Recycle bin - file system directory containing file objects in the user's recycle bin.
' The location of this directory is not in the registry; it is marked with the hidden
' and system attributes to prevent the user from moving or deleting it.
' CSIDL_STARTMENU = &HB ' File system directory containing Start menu items.
' CSIDL_DESKTOPDIRECTORY = &H10 ' File system directory used to physically store file objects on the desktop (not to be confused
' with the desktop folder itself).
' CSIDL_DRIVES = &H11 ' My Computer - virtual folder containing everything on the local computer:
' storage devices, printers, and Control Panel. The folder may also contain mapped network drives.
' CSIDL_NETWORK = &H12 ' Network Neighborhood - virtual folder representing the top level of the network hierarchy.
' CSIDL_NETHOOD = &H13 ' File system directory containing objects that appear in the network neighborhood.
' CSIDL_FONTS = &H14 ' Virtual folder containing fonts.
' CSIDL_TEMPLATES = &H15 ' File system directory that serves as a common repository for document templates.
' CSIDL_COMMON_STARTMENU = &H16 '
' CSIDL_COMMON_PROGRAMS = &H17 '
' CSIDL_COMMON_STARTUP = &H18 '
' CSIDL_COMMON_DESKTOPDIRECT
ORY = &H19 '
' CSIDL_APPDATA = &H1A '
' CSIDL_PRINTHOOD = &H1B '
' CSIDL_ALTSTARTUP = &H1D ' // DBCS
' CSIDL_COMMON_ALTSTARTUP = &H1E ' // DBCS
' CSIDL_COMMON_FAVORITES = &H1F
' CSIDL_INTERNET_CACHE = &H20
' CSIDL_COOKIES = &H21
' CSIDL_HISTORY = &H22
'End Enum
'Private Enum OSVersionEnum
' VER_PLATFORM_WIN32s = 0
' VER_PLATFORM_WIN32_WINDOWS
= 1
' VER_PLATFORM_WIN32_NT = 2
'End Enum
'Public Enum VARENUM
' VT_EMPTY = 0
' VT_NULL = 1
' VT_I2 = 2
' VT_I4 = 3
' VT_R4 = 4
' VT_R8 = 5
' VT_CY = 6
' VT_DATE = 7
' VT_BSTR = 8
' VT_DISPATCH = 9
' VT_ERROR = 10
' VT_BOOL = 11
' VT_VARIANT = 12
' VT_UNKNOWN = 13
' VT_DECIMAL = 14
' VT_I1 = 16
' VT_UI1 = 17
' VT_UI2 = 18
' VT_UI4 = 19
' VT_I8 = 20
' VT_UI8 = 21
' VT_INT = 22
' VT_UINT = 23
' VT_VOID = 24
' VT_HRESULT = 25
' VT_PTR = 26
' VT_SAFEARRAY = 27
' VT_CARRAY = 28
' VT_USERDEFINED = 29
' VT_LPSTR = 30
' VT_LPWSTR = 31
' VT_FILETIME = 64
' VT_BLOB = 65
' VT_STREAM = 66
' VT_STORAGE = 67
' VT_STREAMED_OBJECT = 68
' VT_STORED_OBJECT = 69
' VT_BLOB_OBJECT = 70
' VT_CF = 71
' VT_CLSID = 72
' VT_VECTOR = &H1000&
' VT_ARRAY = &H2000&
' VT_BYREF = &H4000&
' VT_RESERVED = &H8000&
' VT_ILLEGAL = &HFFFF&
' VT_ILLEGALMASKED = &HFFF&
' VT_TYPEMASK = &HFFF&
'End Enum
'/*
' * Queue status flags for GetQueueStatus() and MsgWaitForMultipleObjects(
)
' */
'Public Enum QueueStatusFlags
' QS_KEY = &H1
' QS_MOUSEMOVE = &H2
' QS_MOUSEBUTTON = &H4
' QS_POSTMESSAGE = &H8
' QS_TIMER = &H10
' QS_PAINT = &H20
' QS_SENDMESSAGE = &H40
' QS_HOTKEY = &H80
' QS_ALLPOSTMESSAGE = &H100
' QS_MOUSE = (QS_MOUSEMOVE Or QS_MOUSEBUTTON)
' QS_INPUT = (QS_MOUSE Or QS_KEY)
' QS_ALLEVENTS = (QS_INPUT Or QS_POSTMESSAGE Or QS_TIMER Or QS_PAINT Or QS_HOTKEY)
' QS_ALLINPUT = (QS_INPUT Or QS_POSTMESSAGE Or QS_TIMER Or QS_PAINT Or QS_HOTKEY Or QS_SENDMESSAGE)
'End Enum
Public Const CSIDL_DESKTOP As Long = &H0 ' Windows desktop - virtual folder at the root of the name space.
Public Const CSIDL_INTERNET As Long = &H1 ' Virtual folder representing the Internet
Public Const CSIDL_PROGRAMS As Long = &H2 ' File system directory that contains the userPublic consts program groups (which are also file system directories).
Public Const CSIDL_CONTROLS As Long = &H3 ' Control Panel - virtual folder containing icons for the control panel applications.
Public Const CSIDL_PRINTERS As Long = &H4 ' Printers folder - virtual folder containing installed printers.
Public Const CSIDL_PERSONAL As Long = &H5 ' File system directory that serves as a common respository for documents.
Public Const CSIDL_FAVORITES As Long = &H6 ' Favorite Places - file system folder that stores web (or other) links
Public Const CSIDL_STARTUP As Long = &H7 ' File system directory that corresponds to the userPublic consts Startup program group.
Public Const CSIDL_RECENT As Long = &H8 ' File system directory that contains the userPublic consts most recently used documents.
Public Const CSIDL_SENDTO As Long = &H9 ' File system directory that contains Send To menu items.
Public Const CSIDL_BITBUCKET As Long = &HA ' Recycle bin - file system directory containing file objects in the userPublic consts recycle bin.
' The location of this directory is not in the registry; it is marked with the hidden
' and system attributes to prevent the user from moving or deleting it.
Public Const CSIDL_STARTMENU As Long = &HB ' File system directory containing Start menu items.
Public Const CSIDL_DESKTOPDIRECTORY As Long = &H10 ' File system directory used to physically store file objects on the desktop (not to be confused
' with the desktop folder itself).
Public Const CSIDL_DRIVES As Long = &H11 ' My Computer - virtual folder containing everything on the local computer:
' storage devices, printers, and Control Panel. The folder may also contain mapped network drives.
Public Const CSIDL_NETWORK As Long = &H12 ' Network Neighborhood - virtual folder representing the top level of the network hierarchy.
Public Const CSIDL_NETHOOD As Long = &H13 ' File system directory containing objects that appear in the network neighborhood.
Public Const CSIDL_FONTS As Long = &H14 ' Virtual folder containing fonts.
Public Const CSIDL_TEMPLATES As Long = &H15 ' File system directory that serves as a common repository for document templates.
Public Const CSIDL_COMMON_STARTMENU As Long = &H16 '
Public Const CSIDL_COMMON_PROGRAMS As Long = &H17 '
Public Const CSIDL_COMMON_STARTUP As Long = &H18 '
Public Const CSIDL_COMMON_DESKTOPDIRECT
ORY As Long = &H19 '
Public Const CSIDL_APPDATA As Long = &H1A '
Public Const CSIDL_PRINTHOOD As Long = &H1B '
Public Const CSIDL_ALTSTARTUP As Long = &H1D ' // DBCS
Public Const CSIDL_COMMON_ALTSTARTUP As Long = &H1E ' // DBCS
Public Const CSIDL_COMMON_FAVORITES As Long = &H1F
Public Const CSIDL_INTERNET_CACHE As Long = &H20
Public Const CSIDL_COOKIES As Long = &H21
Public Const CSIDL_HISTORY As Long = &H22
Public Const VER_PLATFORM_WIN32s As Long = 0
Public Const VER_PLATFORM_WIN32_WINDOWS
As Long = 1
Public Const VER_PLATFORM_WIN32_NT As Long = 2
Public Const VT_EMPTY As Long = 0
Public Const VT_NULL As Long = 1
Public Const VT_I2 As Long = 2
Public Const VT_I4 As Long = 3
Public Const VT_R4 As Long = 4
Public Const VT_R8 As Long = 5
Public Const VT_CY As Long = 6
Public Const VT_DATE As Long = 7
Public Const VT_BSTR As Long = 8
Public Const VT_DISPATCH As Long = 9
Public Const VT_ERROR As Long = 10
Public Const VT_BOOL As Long = 11
Public Const VT_VARIANT As Long = 12
Public Const VT_UNKNOWN As Long = 13
Public Const VT_DECIMAL As Long = 14
Public Const VT_I1 As Long = 16
Public Const VT_UI1 As Long = 17
Public Const VT_UI2 As Long = 18
Public Const VT_UI4 As Long = 19
Public Const VT_I8 As Long = 20
Public Const VT_UI8 As Long = 21
Public Const VT_INT As Long = 22
Public Const VT_UINT As Long = 23
Public Const VT_VOID As Long = 24
Public Const VT_HRESULT As Long = 25
Public Const VT_PTR As Long = 26
Public Const VT_SAFEARRAY As Long = 27
Public Const VT_CARRAY As Long = 28
Public Const VT_USERDEFINED As Long = 29
Public Const VT_LPSTR As Long = 30
Public Const VT_LPWSTR As Long = 31
Public Const VT_FILETIME As Long = 64
Public Const VT_BLOB As Long = 65
Public Const VT_STREAM As Long = 66
Public Const VT_STORAGE As Long = 67
Public Const VT_STREAMED_OBJECT As Long = 68
Public Const VT_STORED_OBJECT As Long = 69
Public Const VT_BLOB_OBJECT As Long = 70
Public Const VT_CF As Long = 71
Public Const VT_CLSID As Long = 72
Public Const VT_VECTOR As Long = &H1000&
Public Const VT_ARRAY As Long = &H2000&
Public Const VT_BYREF As Long = &H4000&
Public Const VT_RESERVED As Long = &H8000&
Public Const VT_ILLEGAL As Long = &HFFFF&
Public Const VT_ILLEGALMASKED As Long = &HFFF&
Public Const VT_TYPEMASK As Long = &HFFF&
Public Const QS_KEY As Long = &H1
Public Const QS_MOUSEMOVE As Long = &H2
Public Const QS_MOUSEBUTTON As Long = &H4
Public Const QS_POSTMESSAGE As Long = &H8
Public Const QS_TIMER As Long = &H10
Public Const QS_PAINT As Long = &H20
Public Const QS_SENDMESSAGE As Long = &H40
Public Const QS_HOTKEY As Long = &H80
Public Const QS_ALLPOSTMESSAGE As Long = &H100
Public Const QS_MOUSE As Long = (QS_MOUSEMOVE Or QS_MOUSEBUTTON)
Public Const QS_INPUT As Long = (QS_MOUSE Or QS_KEY)
Public Const QS_ALLEVENTS As Long = (QS_INPUT Or QS_POSTMESSAGE Or QS_TIMER Or QS_PAINT Or QS_HOTKEY)
Public Const QS_ALLINPUT As Long = (QS_INPUT Or QS_POSTMESSAGE Or QS_TIMER Or QS_PAINT Or QS_HOTKEY Or QS_SENDMESSAGE)
Public Const BIF_RETURNONLYFSDIRS As Long = &H1
Public Const BIF_DONTGOBELOWDOMAIN As Long = &H2
Public Const BIF_STATUSTEXT As Long = &H4
Public Const BIF_RETURNFSANCESTORS As Long = &H8
Public Const BIF_BROWSEFORCOMPUTER As Long = &H1000
Public Const BIF_BROWSEFORPRINTER As Long = &H2000
Public Type SHITEMID ' Shell item identifier
cb As Long
abID As Byte
End Type
Public Type ITEMIDLIST ' Shell item identifier list
mkid As SHITEMID
End Type
Public Type BROWSEINFO ' shell structure used to browse for folders
hOwner As Long
pidlRoot As Long
pszDisplayName As String
lpszTitle As String
ulFlags As Long
lpfn As Long
lParam As Long
iImage As Long
End Type
'Public Enum BrowseFolderFlags ' flags used to browse for folders
' BIF_RETURNONLYFSDIRS = &H1
' BIF_DONTGOBELOWDOMAIN = &H2
' BIF_STATUSTEXT = &H4
' BIF_RETURNFSANCESTORS = &H8
' BIF_BROWSEFORCOMPUTER = &H1000
' BIF_BROWSEFORPRINTER = &H2000
'End Enum
Private Type OSVERSIONINFO ' operating system version information [used by GetVersion]
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
szCSDVersion As String * 128 ' Maintenance string for PSS usage
End Type
Private Type tagDECIMAL
wReserved As Integer
scale As Byte ' // The number of decimal places for the
' // number. Valid values are from 0 to 28. So
' // 12.345 is represented as 12345 with a
' // scale of 3.
sign As Byte ' // 0 for positive numbers or DECIMAL_NEG for
' // negative numbers. So -1 is represented as
' // 1 with the DECIMAL_NEG bit set.
Hi32 As Long ' unsigned
Lo32 As Long ' unsigned
Mid32 As Long ' unsigned
End Type
Public Type SAFEARRAYBOUND
cElements As Long ' # of elements in the array dimension
lLbound As Long ' lower bounds of the array dimension
End Type
Public Type SAFEARRAY
cDims As Integer ' // Count of dimensions in this array.
fFeatures As Integer ' // Flags used by the SafeArray
' // routines documented below.
cbElements As Long ' // Size of an element of the array.
' // Does not include size of
' // pointed-to data.
cLocks As Long ' // Number of times the array has been
' // locked without corresponding unlock.
pvData As Long ' // Pointer to the data.
' Should be sized to cDims:
rgsabound() As SAFEARRAYBOUND ' // One bound for each dimension.
End Type
'=========================
==========
==========
==========
==========
==========
' Private members
'=========================
==========
==========
==========
==========
==========
Private OSVersion As OSVERSIONINFO ' private structure for various Public functions
Private Success As Boolean ' general return code [boolean]
Private ReturnVal As Long ' general return code [various]
Private ErrCode As Long ' general return code [error]
'=========================
==========
==========
==========
==========
==========
' Declares
'=========================
==========
==========
==========
==========
==========
Public Declare Sub SetLastError Lib "kernel32" (ByVal dwErrCode As Long)
Private Declare Function SHGetPathFromIDListA Lib "shell32.dll" (ByVal Pidl As Long, ByVal pszPath As String) As Long
Private Declare Function SHGetPathFromIDListW Lib "shell32.dll" (ByVal Pidl As Long, ByVal pszPath As Long) As Long
Private Declare Function SHGetSpecialFolderLocation
Lib "shell32.dll" (ByVal hwndOwner As Long, ByVal nFolder As Long, Pidl As ITEMIDLIST) As Long
Private Declare Function SHBrowseForFolder Lib "shell32.dll" Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long 'ITEMIDLIST
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long
Public Declare Function SendMessageA Lib "user32" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Declare Function SendMessageW Lib "user32" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function WNetGetUserA Lib "mpr.dll" (ByVal lpName As String, ByVal lpUserName As String, lpnLength As Long) As Long
Private Declare Function WNetGetUserW Lib "mpr.dll" (ByVal lpName As Long, ByVal lpUserName As Long, lpnLength As Long) As Long
Private Declare Function GetUserNameA Lib "advapi32.dll" (ByVal lpBuffer As String, nSize As Long) As Long
Private Declare Function GetUserNameW Lib "advapi32.dll" (ByVal lpBuffer As Long, nSize As Long) As Long
Private Declare Function GetComputerNameA Lib "kernel32" (ByVal lpBuffer As String, nSize As Long) As Long
Private Declare Function GetComputerNameW Lib "kernel32" (ByVal lpBuffer As Long, nSize As Long) As Long
Private Declare Function GetModuleFileNameA Lib "kernel32" (ByVal hModule As Long, ByVal lpFilename As String, ByVal nSize As Long) As Long
Private Declare Function GetModuleFileNameW Lib "kernel32" (ByVal hModule As Long, ByVal lpFilename As Long, ByVal nSize As Long) As Long
Private Declare Function RasGetErrorStringA Lib "RasApi32.DLL" (ByVal uErrorValue As Long, ByVal lpszErrorString As String, ByVal cBufSize As Long) As Long
Private Declare Function RasGetErrorStringW Lib "RasApi32.DLL" (ByVal uErrorValue As Long, ByVal lpszErrorString As Long, ByVal cBufSize As Long) As Long
Public Declare Sub CopyMemoryAny Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal nBytes As Long)
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal lpDest As Long, ByVal lpSource As Long, ByVal nBytes As Long)
Public Declare Sub ZeroMemory Lib "kernel32" Alias "RtlZeroMemory" (ByVal lpSource As Long, ByVal nBytes As Long)
Private Declare Function FormatMessageA Lib "kernel32" (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Arguments As Long) As Long
Private Declare Function FormatMessageW Lib "kernel32" (ByVal dwFlags As Long, ByVal lpSource As Long, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As Long, ByVal nSize As Long, Arguments As Long) As Long
Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long
Private Declare Function lstrlenA Lib "kernel32" (lpString As Any) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
' LastDllErrorMsg related functions
Private Declare Function GetModuleHandleA Lib "kernel32" (ByVal lpModuleName As String) As Long
Private Declare Function InternetGetLastResponseInf
oA Lib "WinInet.dll" _
(lpdwError As Long, ByVal lpszBuffer As String, lpdwBufferLength As Long) As Long
Private Declare Function WNetGetLastErrorA Lib "mpr.dll" _
(lpError As Long, ByVal lpErrorBuf As String, ByVal nErrorBufSize As Long, _
ByVal lpNameBuf As String, ByVal nNameBufSize As Long) As Long
Private Declare Function WNetGetLastErrorW Lib "mpr.dll" _
(lpError As Long, ByVal lpErrorBuf As Long, ByVal nErrorBufSize As Long, _
ByVal lpNameBuf As Long, ByVal nNameBufSize As Long) As Long
Private Declare Function SafeArrayGetDim Lib "oleaut32" (psa As Long) As Long
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function WaitForMultipleObjects Lib "kernel32" (ByVal nCount As Long, lpHandles As Long, ByVal bWaitAll As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function WaitForMultipleObjectsEx Lib "kernel32" (ByVal nCount As Long, lpHandles As Long, ByVal bWaitAll As Long, ByVal dwMilliseconds As Long, ByVal bAlertable As Long) As Long
Private Declare Function MsgWaitForMultipleObjectsE
x Lib "user32" ( _
ByVal nCount As Long, pHandles As Long, ByVal dwMilliseconds As Long, ByVal dwWakeMask As Long, ByVal dwFlags As Long) As Long
Private Declare Function MsgWaitForMultipleObjects Lib "user32" (ByVal nCount As Long, pHandles As Long, ByVal fWaitAll As Long, ByVal dwMilliseconds As Long, ByVal dwWakeMask As Long) As Long
Private Declare Function CreateEvent Lib "kernel32" Alias "CreateEventA" (lpEventAttributes As Any, ByVal bManualReset As Long, ByVal bInitialState As Long, ByVal lpName As String) As Long
Private Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal pv As Long)
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function timeGetTime Lib "winmm.dll" () As Long
Public Function BrowseForFolder( _
ByVal hwnd As Long, _
Optional ByVal TopFolder As Long = CSIDL_DESKTOP, _
Optional ByVal Title As String = "Select folder", _
Optional ByVal Flags As Long = BIF_RETURNONLYFSDIRS, _
Optional ByVal DefaultFolder As String) As String
'=========================
==========
==========
==========
==========
==========
' BrowseForFolder - Allows the user to browse for a folder using
' the shell namespace.
'
' TopFolder Identifies the root folder.
' Title Attaches a description above the TreeView.
' Flags Misc flags defining behavior.
' DefaultFolder Reserved.
'=========================
==========
==========
==========
==========
==========
Dim bi As BROWSEINFO ' input structure used by Shell API
Dim idl As ITEMIDLIST ' input structure used by Shell API
Dim Result As Long ' return code
Dim Pidl As Long ' pointer to an Item ID List
Dim Path As String ' resulting path returned
Dim Pos As Integer ' parsing index
' Return default value if canceled
BrowseForFolder = DefaultFolder
With bi
.hOwner = hwnd
' Convert virtual folder to pidl
Result = SHGetSpecialFolderLocation
(hwnd, TopFolder, idl)
.pidlRoot = idl.mkid.cb
' set the dialog title
.lpszTitle = Title
' input options
.ulFlags = Flags
' Give callback info about default folder
If Len(DefaultFolder) > 0 Then
' Set address of callback function
.lpfn = ProcAddress(AddrOf(BrowseC
allbackPro
c)) ' <-- ERRORS
' Convert to Ansi if not on NT
If Not IsWinNt Then
DefaultFolder = StrConv(DefaultFolder, vbFromUnicode)
End If
' Store pointer to default folder
.lParam = StrPtr(DefaultFolder)
End If
End With
' display browse dialog
Pidl = SHBrowseForFolder(bi)
' Make sure Cancel not clicked
If Pidl <> 0 Then
' size of the buffer to fit & pad with nulls
Path = Space$(519) & vbNullChar
' copy the path to local buffer
If CBool(SHGetPathFromIDList(
Pidl, Path)) Then
' strip off null terminators
Pos = InStr(Path, Chr$(0))
BrowseForFolder = Left$(Path, Pos - 1)
End If
' Release the pidl!
CoTaskMemFree Pidl
End If
End Function
Public Function BrowseCallbackProc( _
ByVal hwnd As Long, _
ByVal uMsg As Long, _
ByVal lParam As Long, _
ByVal lpData As Long) As Long
Const WM_USER As Long = &H400
Const BFFM_INITIALIZED As Long = 1
' // messages to browser
Const BFFM_SETSELECTIONA As Long = (WM_USER + 102)
Const BFFM_SETSELECTIONW As Long = (WM_USER + 103)
Static ExitProc As Boolean
If ExitProc Then Exit Function
Select Case uMsg
Case BFFM_INITIALIZED
' Avoid reentry resulting from dialog
' another firing a BFFM_INITIALIZED when
' it receives a BFFM_SETSELECTION.
ExitProc = True
' Tell tree browser to select the path
' pointed to at lpData.
If IsWinNt() Then
SendMessageA hwnd, BFFM_SETSELECTIONW, Abs(True), ByVal lpData
Else
SendMessageW hwnd, BFFM_SETSELECTIONA, Abs(True), ByVal lpData
End If
' Allow reentry
ExitProc = False
End Select
End Function
Public Function LoBite(ByVal wParam As Integer) As Byte
LoBite = wParam And &HFF
End Function
Public Function LoByte(ByVal wParam As Integer) As Byte
LoByte = wParam And &HFF
End Function
Public Function HiByte(ByVal wParam As Integer) As Byte
HiByte = (wParam And &HFF00&) \ 256
End Function
Public Function HiWord(ByVal lParam As Long) As Long
'=========================
==========
==========
==========
==========
==========
' HiWord - Returns Hi Word part of the supplied dual long value which is often needed
' when working with long values returned by API calls.
'
' lParam Input. Dual value returned by API call.
'
' RETURNS the high order word of the supplied long value
'=========================
==========
==========
==========
==========
==========
HiWord = (lParam And &HFFFF0000) \ &H10000
End Function
Public Function LoWord(ByVal lParam As Long) As Long
'=========================
==========
==========
==========
==========
==========
' LoWord - Returns Lo Word part of the supplied dual long value which is often needed
' when working with long values returned by API calls.
'
' lParam Input. Dual value returned by API call.
'
' RETURNS the low order word of the supplied long value
'=========================
==========
==========
==========
==========
==========
If (lParam And &H8000&) <> 0 Then
LoWord = lParam Or &HFFFF0000
Else
LoWord = lParam And &HFFFF&
End If
End Function
Function MakeWord(ByVal LoByte As Byte, ByVal HiByte As Byte) As Integer
'=========================
==========
==========
==========
==========
==========
' MakeWord - Packs 2 8-bit integers into a 16-bit integer.
'=========================
==========
==========
==========
==========
==========
If (HiByte And &H80) <> 0 Then
MakeWord = ((HiByte * 256&) + LoByte) Or &HFFFF0000
Else
MakeWord = (HiByte * 256) + LoByte
End If
End Function
Public Function MakeDWord(ByVal LoWord As Integer, ByVal HiWord As Integer) As Long
'=========================
==========
==========
==========
==========
==========
' MakeDWord - Packs 2 16-bit integers into a 32-bit Long.
'
' HiWord The most significant 16 bits.
'
' LoWord The least significant 16 bits.
'
' RETURNS: A Long holding the full 32-bit value.
'=========================
==========
==========
==========
==========
==========
MakeDWord = (HiWord * 65536) + (LoWord And &HFFFF&)
End Function
Public Function HexBytes(ByteArray) As String
'=========================
==========
==========
==========
==========
==========
' HexByte - Returns a hex string representation of the supplied bite.
'=========================
==========
==========
==========
==========
==========
Dim i As Long
' Sanity check input array
If VarType(ByteArray) <> vbByte + vbArray Then
Err.Raise 13, Module
End If
For i = LBound(ByteArray) To UBound(ByteArray)
If Len(Hex$(ByteArray(i))) = 1 Then
HexBytes = HexBytes & "0" & LCase$(Hex$(ByteArray(i)))
& " "
Else
HexBytes = HexBytes & LCase$(Hex$(ByteArray(i)))
& " "
End If
Next i
End Function
Public Function HexWORD(ByVal WORD As Long, Optional ByVal Prefix As String) As String
'=========================
==========
==========
==========
==========
==========
' HexDWORD - Returns a hex string representation of a WORD.
'
' WORD The 2 byte value to convert to a hex string.
' Prefix A value such as "0x" or "&H".
'
' NOTE: It's up to the caller to ensure the subject value is a 16-bit number.
'=========================
==========
==========
==========
==========
==========
Dim Bytes(1 To 2) As Byte
Dim i As Long
CopyMemory ByVal VarPtr(Bytes(1)), ByVal VarPtr(WORD), 4
HexWORD = Prefix
For i = UBound(Bytes) To LBound(Bytes) Step -1
If Len(Hex$(Bytes(i))) = 1 Then
HexWORD = HexWORD & "0" & LCase$(Hex$(Bytes(i)))
Else
HexWORD = HexWORD & LCase$(Hex$(Bytes(i)))
End If
Next i
End Function
Public Function HexDWORD(ByVal DWORD As Long, Optional ByVal Prefix As String) As String
'=========================
==========
==========
==========
==========
==========
' HexDWORD - Returns a hex string representation of a DWORD.
'
' DWORD The 4 byte value to convert to a hex string.
' Prefix A value such as "0x" or "&H".
'=========================
==========
==========
==========
==========
==========
Dim Bytes(1 To 4) As Byte
Dim i As Long
CopyMemory ByVal VarPtr(Bytes(1)), ByVal VarPtr(DWORD), 4
HexDWORD = Prefix
For i = UBound(Bytes) To LBound(Bytes) Step -1
If Len(Hex$(Bytes(i))) = 1 Then
HexDWORD = HexDWORD & "0" & LCase$(Hex$(Bytes(i)))
Else
HexDWORD = HexDWORD & LCase$(Hex$(Bytes(i)))
End If
Next i
End Function
Public Function HexQUAD(QWORD, Optional ByVal Prefix As String) As String
'=========================
==========
==========
==========
==========
==========
' HexQUAD - Returns a hex string representation of a QWORD/QWORD.
'
' QWORD The decimal value to convert to a hex string.
' Prefix A value such as "0x" or "&H".
'=========================
==========
==========
==========
==========
==========
Dim Bytes(1 To 8) As Byte
Dim i As Long
' Sanity check input array
If VarType(QWORD) <> vbDecimal Then
Err.Raise 13, Module
End If
' We only copy the first 8 bytes of the decimal value.
CopyMemory ByVal VarPtr(Bytes(1)), ByVal VarPtr(LoDWord(QWORD)), 4
CopyMemory ByVal VarPtr(Bytes(1)) + 4, ByVal VarPtr(HiDWord(QWORD)), 4
HexQUAD = Prefix
For i = UBound(Bytes) To LBound(Bytes) Step -1
If Len(Hex$(Bytes(i))) = 1 Then
HexQUAD = HexQUAD & "0" & LCase$(Hex$(Bytes(i)))
Else
HexQUAD = HexQUAD & LCase$(Hex$(Bytes(i)))
End If
Next i
End Function
Public Function HexEncodeData(Data, DisplayFormat As Long, Optional Prefix As String) As String
'=========================
==========
==========
==========
==========
==========
' HexEncodeData - Returns a hex string representation of the supplied binary data.
'=========================
==========
==========
==========
==========
==========
Dim Bytes() As Byte ' "String" varsion of "Data" converted to this
Dim iStep As Long ' iterator step
Dim Value As Variant ' Integer, Lond or Decimal data
Dim lValue As Long
Dim lValueHi As Long
Dim cbValue As Long
Dim nElements As Long ' # of elements in the byte array
Dim EncodedStr As String ' Encoded string like "0x00000000"
Dim lpValue As Long
Dim ccValue As Long ' # of characters
Dim i As Long
Dim j As Long
' Sanity check input array
Select Case VarType(Data)
Case vbByte + vbArray
' default data type to encode
Case vbString
Bytes = Data
' NOTE: Caller should consider converting the string to ANSI
HexEncodeData = HexEncodeData(Bytes, DisplayFormat)
Exit Function
Case Else
Err.Raise 13, Module
End Select
Select Case DisplayFormat
Case efHexBytes
' Don't loop if returning "byte" encoded values, just
' hand off the entire processing to another function.
HexEncodeData = HexBytes(Data)
Exit Function
Case efHexWORDS
iStep = 2
Case efHexDWORDs
iStep = 4
Case efHexQWORDs
iStep = 8
Case Else
Err.Raise 5, Module
End Select
' Count # of elements in the array and ensure
' the array is fixed to the size of the output
' format.
nElements = Abs((LBound(Data)) - (UBound(Data))) + 1
If nElements Mod iStep <> 0 Then
Err.Raise 5, Module, "Size of input data does not match output format."
End If
' Size the output buffer to fit what will be returned.
' We do this because we don't want to perform any string
' concatenation which will kill our performance.
ccValue = iStep + Len(Prefix) + 1 ' the "+ 1" is the (space) delimiter
HexEncodeData = String((ccValue * nElements) - 1, " ")
' Loop thru entire array in 2, 4, or 8 byte increments.
For i = LBound(Data) To UBound(Data) Step iStep
' Track # of actual conversions
j = j + 1
lpValue = VarPtr(Data(i))
Select Case DisplayFormat
Case efHexWORDS
cbValue = nElements Mod 2
If cbValue = 0 Then cbValue = 2
CopyMemory ByVal VarPtr(lValue), ByVal lpValue, cbValue
EncodedStr = HexWORD(lValue, Prefix)
Case efHexDWORDs
cbValue = nElements Mod 4
If cbValue = 0 Then cbValue = 4
CopyMemory ByVal VarPtr(lValue), ByVal lpValue, ByVal cbValue
EncodedStr = HexDWORD(lValue, Prefix)
Case efHexQWORDs
cbValue = nElements Mod 8
If cbValue = 0 Then cbValue = 8
CopyMemory ByVal VarPtr(lValue), ByVal lpValue, cbValue
CopyMemory ByVal VarPtr(lValueHi), ByVal lpValue + 4, cbValue
EncodedStr = HexQUAD(MakeDecimal(lValue
Hi, lValue), Prefix)
End Select
' Copy ONLY the bytes that represent the encoded value.
' The "* 2" is to account for Unicode.
CopyMemory ByVal StrPtr(HexEncodeData) + (ccValue * 2) * (j - 1), _
ByVal StrPtr(EncodedStr), Len(EncodedStr) * 2
Next i
End Function
Public Function ProcAddress(ByVal lpFunction As Long) As Long
'=========================
==========
==========
==========
==========
==========
' ProcAddress - Returns the address of the supplied function.
'
' lpFunction Function name. Passed "AddressOf <name>"
'
' RETURNS The 32 bit address of the function.
'=========================
==========
==========
==========
==========
==========
ProcAddress = lpFunction
End Function
Public Function IsWinNt() As Boolean
'=========================
==========
==========
==========
==========
==========
' IsWinNT - Returns true if we're running Windows NT.
'=========================
==========
==========
==========
==========
==========
' NOTE: OSVERSIONINFO is defined at the module
' for imporved performance.
If OSVersion.dwOSVersionInfoS
ize = 0 Then ' this is our first time making this call
OSVersion.dwOSVersionInfoS
ize = Len(OSVersion) ' initialize so API knows which version being used
GetVersionEx OSVersion ' make the call once & then save/re-use it
End If
IsWinNt = OSVersion.dwPlatformId = VER_PLATFORM_WIN32_NT ' return the result
End Function
Public Function WinMajor() As Long
If OSVersion.dwOSVersionInfoS
ize = 0 Then ' this is our first time making this call
OSVersion.dwOSVersionInfoS
ize = Len(OSVersion) ' initialize so API knows which version being used
GetVersionEx OSVersion ' make the call once & then save/re-use it
End If
WinMajor = OSVersion.dwMajorVersion ' return the result
End Function
Public Function IsWin98OrLater() As Boolean
If OSVersion.dwOSVersionInfoS
ize = 0 Then ' this is our first time making this call
OSVersion.dwOSVersionInfoS
ize = Len(OSVersion) ' initialize so API knows which version being used
GetVersionEx OSVersion ' make the call once & then save/re-use it
End If
If OSVersion.dwMajorVersion > 4 Then
IsWin98OrLater = True
ElseIf OSVersion.dwMajorVersion = 4 _
And OSVersion.dwMinorVersion > 0 Then
IsWin98OrLater = True
End If
End Function
Public Function GetUserId() As String
'=========================
==========
==========
==========
==========
==========
' GetUserId
'
' RETURNS On success, the user name currently logged on to the network. If not
' logged on to the network, returns the user id logged on to the system.
' On failure, an empty string.
'=========================
==========
==========
==========
==========
==========
Dim UserID As String ' The user currently logged on
Dim ErrorCode As Long ' result
Dim Success As Boolean ' result
Dim Buffer As String ' output buffer
Dim BufferLen As Long ' size of the output buffer
On Error GoTo ErrHandler ' trap all errors
If Len(UserID) > 0 Then ' we already know this info
GoTo ExitLabel ' we're done
End If
Buffer = String(255, 0) ' pad buffer with nulls
BufferLen = Len(Buffer) ' remember size of output buffer
' Fetch id user logged on to network [if logged on]
ErrorCode = WNetGetUser(vbNullString, Buffer, BufferLen)
If ErrorCode = 0 Then ' user is logged on to the network
UserID = TrimNulls(Buffer) ' kill null terminators
Else ' not logged on to the network
Success = GetUserName(Buffer, BufferLen) ' get Windows' current user value
If Success Then
UserID = TrimNulls(Buffer) ' kill null terminators
End If
End If
ExitLabel:
GetUserId = UserID ' return the requested info
Exit Function
Resume
ErrHandler:
Exit Function ' just exit & return null string
End Function
Public Function TrimNulls(InString As String) As String
'=========================
==========
==========
==========
==========
==========
' TrimNulls - Trims null terminators from a string.
'
' InString The string to strip nulls from.
'
' RETURNS The resulting string.
'=========================
==========
==========
==========
==========
==========
Dim Pos As Long ' location of null terminator
Pos = InStr(InString, Chr$(0)) ' find null terminator
If Pos > 0 Then ' terminator located
TrimNulls = Left$(InString, Pos - 1) ' strip terminator
Else ' no terminator found
TrimNulls = InString ' return the supplied input string
End If
End Function
Public Function ComputerName() As String
'=========================
==========
==========
==========
==========
==========
' ComputerName - Returns the name of the local machine.
'=========================
==========
==========
==========
==========
==========
Dim NameLength As Long
' size buffer to fit
ComputerName = String(MAX_COMPUTERNAME_LE
NGTH + 1, 0)
NameLength = Len(ComputerName)
' Get the computer name
Success = GetComputerName(ComputerNa
me, NameLength)
If Success Then
' strip null terminators
ComputerName = Left$(ComputerName, NameLength)
Else
ApiRaise
End If
End Function
Public Function LastDllErrorMsg(Optional ByVal Number As Long, _
Optional ByVal NewLineCharacter As String = vbCrLf) As String
'=========================
==========
==========
==========
==========
==========
====
' LastDllErrorMsg - Returns the description of the supplied error number.
'
' Number Optional. The number to decode if supplied, otherwise the
' Err.LastDllError is used.
' NewLineCharacter Optional. Use to specificy an alternate character for CR/LFs
'=========================
==========
==========
==========
==========
==========
====
Const ERROR_INSUFFICIENT_Message
= 122&
Const FORMAT_MESSAGE_FROM_HMODUL
E = &H800&
Const FORMAT_MESSAGE_FROM_SYSTEM
= &H1000&
Const ERROR_EXTENDED_ERROR = 1208&
Dim Message As String ' Place where error description will be nSize to.
Dim Provider As String ' Place where error next provider output to
Dim nSize As Long ' Number of bytes nSize to Message
Dim Result As Long ' general return code
Dim Success As Boolean
Dim ErrorCode As Long
Dim PreservedDllErr As Long ' saved error number; since error functions w/be calling this
On Error GoTo ExitLabel ' There shouldnt be any errors here.
PreservedDllErr = Err.LastDllError ' save LastDllError as it will be restored on exit
If Number = 0 Then ' no error code supplied
Number = Err.LastDllError ' use the VB last known API error code
ElseIf (Number And &H8000&) = 0 Then ' 'possible' HRESULT
' NOTE: We must often contend with errors returned by VB
' and other interfaces with a description of "OLE Automation Error".
' These HRESULTS can OFTEN be translated to a Windows' system error
' by it's low word. This is typical when trying to create an object
' (perhaps via DCOM) or when accessing an object via a system
' interface such as IShellFolder.
Number = Number And &HFFFF& ' Essentially, we strip vbObjectError
End If
' init output Message & clear LastDllError
SetLastError 0
nSize = 0
' Translate generic error descriptions
Select Case Number
Case ERROR_EXTENDED_ERROR
' server has extended error info
' Initialize output buffers
Message = String(512, 0)
Provider = String(128, 0)
' Get the error info from the server
Result = WNetGetLastErrorA(ErrorCod
e, Message, Len(Message), Provider, Len(Provider))
If Result = 0 Then
' call succeeded
' Strip NULLs from the strings
Message = TrimNulls(Message)
Provider = TrimNulls(Provider)
End If
' Build friendly message
Message = Provider & " returned error #" & ErrorCode & " " & Message & "."
nSize = Len(Message)
Case 600 To 799
' RAS specific codes have an error base of 600
' Initialize our Message and translate the error code
Message = String(512, 0)
nSize = Len(Message)
Result = RasGetErrorStringA(Number,
Message, nSize)
If Result = 0 Then
' call succeeded
' Fetch message size
nSize = InStr(Message, vbNullChar) - 1
' Sanity check
If nSize < 0 Then nSize = 0
End If
Case 12003 'ERROR_INTERNET_EXTENDED_E
RROR
' wininet extended errors
' Fetch Message size needed
nSize = 0
Success = InternetGetLastResponseInf
oA(Result,
Message, nSize)
' Size Message to fit
Message = String(nSize + 1, 0)
Success = InternetGetLastResponseInf
oA(Result,
Message, (nSize))
' **************************
**********
**********
**********
' BTW: Parsing this string may allow us to re-map
' to a real error. This is where we end up when
' the wininet parser fails (even on simple things
' that might not represent an error condition).
' **************************
**********
**********
**********
' CALLER should call my function MapFtpResponse() which
' will attempt to map an FTP response code marked as
' ERROR_INTERNET_EXTENDED_ER
ROR to a matching Win32 error.
' **************************
**********
**********
**********
Case 12000 To 12999
' wininet specific errors
' This functions assume that wininet.dll is already mapped into memory
Result = GetModuleHandleA("wininet.
dll")
If Result <> 0 Then
' Initialize our Message and translate the error code
Message = Space(256)
nSize = _
FormatMessageA(FORMAT_MESS
AGE_FROM_H
MODULE, _
ByVal Result, Number, 0&, Message, 255, ByVal 0&)
' Else: we could be nice and temporarily load the library
End If
Case Else
' All other Windows errors
' Initialize our Message and translate the error code
Message = Space(256)
nSize = _
FormatMessageA(FORMAT_MESS
AGE_FROM_S
YSTEM, _
ByVal 0&, Number, 0&, Message, 255&, ByVal 0&)
End Select
' return the error description
LastDllErrorMsg = Left$(Message, nSize)
' If the caller wants to translate line breaks then do so
If StrComp(NewLineCharacter, vbCrLf, vbBinaryCompare) <> 0 Then
LastDllErrorMsg = Replace(LastDllErrorMsg, vbCrLf, Left$(NewLineCharacter, 1))
End If
' Strip ending CR/LF's as many message tables like to add this.
If Right$(LastDllErrorMsg, 2) = vbCrLf Then
LastDllErrorMsg = Left$(LastDllErrorMsg, Len(LastDllErrorMsg) - 2)
End If
' Terminate description with a period if not.
Select Case Right$(LastDllErrorMsg, 1)
Case ".", "?", "!"
' this case not very locale friendly
Case Else
LastDllErrorMsg = LastDllErrorMsg & "."
End Select
ExitLabel:
' Restore Err.LastDllError value is it was on entry
SetLastError PreservedDllErr
Debug.Assert (Err.Number = 0)
End Function
Public Function IsValidHandle(ByVal Handle As Long) As Boolean
Const INVALID_HANDLE_VALUE = -1
Select Case Handle
Case 0, INVALID_HANDLE_VALUE
Case Else
IsValidHandle = True
End Select
End Function
Public Function InvalidHandleValue(ByVal Handle As Long) As Boolean
Const INVALID_HANDLE_VALUE = -1
Select Case Handle
Case 0, INVALID_HANDLE_VALUE
InvalidHandleValue = True
End Select
End Function
Public Function PtrToStr(lpString As Long, Optional nBytes As Long = -1) As String
'=========================
==========
==========
==========
==========
==========
' PtrToStr - Wrapper function for PtrToStrA and PtrToStrW based on the current
' operating system.
'=========================
==========
==========
==========
==========
==========
If IsWinNt Then
PtrToStr = PtrToStrW(lpString, nBytes)
Else
PtrToStr = PtrToStrA(lpString, nBytes)
End If
End Function
Public Function PtrToStrA(ByVal lpString As Long, _
Optional ByVal nBytes As Long = -1) As String
'=========================
==========
==========
==========
==========
==========
' PtrToStrA - Converts a pointer to a ANSI string to a BSTR (string).
'
' lpString Pointer to an ANSI string.
' nBytes The size of the string in bytes. If -1, then lpString is
' assumed to be null terminated.
'
' RETURNS The string as pointed to by lpString, or vbNullString
' if lpString is zero.
'=========================
==========
==========
==========
==========
==========
Dim Buffer() As Byte ' size of buffer
PtrToStrA = vbNullString ' return null pointer by default
Select Case lpString ' validate the pointer
Case 0, INVALID_HANDLE_VALUE ' bogus pointer supplied
Exit Function ' return an empty string for null address
End Select
If nBytes = 0 Then ' zero length string
Exit Function ' we're done
ElseIf nBytes = -1 Then
nBytes = lstrlenA(ByVal lpString) ' how big is the string?
End If
If nBytes <= 0 Then Exit Function ' exit if empty
ReDim Buffer(1 To nBytes) ' size array to fit
CopyMemory ByVal VarPtr(Buffer(1)), _
ByVal lpString, nBytes ' copy string to byte array work area
PtrToStrA = StrConv(Buffer, vbUnicode) ' convert to Unicode
End Function
Public Function PtrToStrW(ByVal lpString As Long, _
Optional ByVal nBytes As Long = -1) As String
'=========================
==========
==========
==========
==========
==========
' PtrToStrW - Converts a pointer to a WIDE string to a BSTR (string).
'
' lpString Pointer to a WIDE string.
' nBytes The size of the string in bytes. If -1, then lpString is
' assumed to be null terminated.
'
' RETURNS The string as pointed to by lpString, or vbNullString
' if lpString is zero.
'=========================
==========
==========
==========
==========
==========
Dim Buffer() As Byte ' size of buffer
PtrToStrW = vbNullString ' return null pointer by default
Select Case lpString ' validate the pointer
Case 0, INVALID_HANDLE_VALUE ' bogus pointer supplied
Exit Function ' return an empty string for null address
End Select
If nBytes = 0 Then ' zero length string
Exit Function ' we're done
ElseIf nBytes = -1 Then
nBytes = lstrlenW(lpString) * 2 ' how big is the string?
End If
If nBytes <= 0 Then Exit Function ' exit if empty
ReDim Buffer(1 To nBytes) ' size array to fit
CopyMemory ByVal VarPtr(Buffer(1)), _
ByVal lpString, nBytes ' copy string to byte array work area
PtrToStrW = Buffer ' Return the Unicode string
End Function
Public Function PtrToData(ByVal lpData As Long, ByVal DataType As Long, _
Optional ByVal Length As Long = -1) As Variant
'=========================
==========
==========
==========
==========
==========
' PtrToData - This functions takes a long pointer to a data element and
' converts it to a variant of subtype DataType.
'
' lpData Pointer to the data element to convert.
' DataType Type of data being converted.
' Length Optional. Size of data [vbString and vbByte+vbArray only].
' However, in some cases we allow this member to be set.
' For instance, a caller may only need to copy the first 8
' bytes in the case of a Decimal data type which would be
' typical when working with API's and 64 bit values split
' into DWORDs.
'
' RETURNS The data element as a variant.
'=========================
==========
==========
==========
==========
==========
Dim VType As Integer ' the VARTYPE member of the VARIANT structure
On Error GoTo ErrHandler
' This SELECT CASE identifies the data type and initializes VARTYPE.
' The actual data is copied after the switch, except for the exceptions
' such as byte array, currency and string data types which are handled
' in-line.
Select Case DataType
Case vbByte
PtrToData = CByte(PtrToData)
Length = 1
Case vbBoolean
PtrToData = CBool(PtrToData)
If Length = -1 Then Length = 2
Case vbInteger
PtrToData = CInt(PtrToData)
If Length = -1 Then Length = 2
Case vbLong
PtrToData = CLng(PtrToData)
If Length = -1 Then Length = 4
Case vbSingle
PtrToData = CSng(PtrToData)
Length = 4
Case vbDate
PtrToData = CDate(PtrToData)
Length = 8
Case vbDouble
PtrToData = CDbl(PtrToData)
Length = 8
Case vbDecimal
' Caller should use MakeDecimal
Err.Raise 5
Case vbObject
Set PtrToData = PtrToObj(lpData)
GoTo ExitLabel
Case (vbByte Or vbArray)
Dim bArray() As Byte
' Size temp array to fit
ReDim bArray(1 To Length)
' Copy the data into the array
CopyMemory ByVal VarPtr(bArray(1)), ByVal lpData, Length
' return the array
PtrToData = bArray
GoTo ExitLabel
Case vbCurrency
' This case handled out of the switch because of scaling
PtrToData = CCur(PtrToData)
Length = 8
' Copy the data into return value
CopyMemory ByVal VarPtr(PtrToData) + 8, ByVal lpData, Length
' Handle the scale
PtrToData = PtrToData * 10000
GoTo ExitLabel
Case vbString
' Assumed to be a VB native WIDE string
' Convert to unicode string
PtrToData = PtrToStrW(lpData, Length)
GoTo ExitLabel
Case Else
' we should never be here
Debug.Assert 0
' Throw error to caller
On Error GoTo 0
Err.Raise 5
End Select
' NOTE: A Variant's descriptor, padding & union take up 8 bytes.
' Copy the data into return value
CopyMemory ByVal VarPtr(PtrToData) + 8, ByVal lpData, Length
ExitLabel:
Exit Function
Resume
ErrHandler:
Debug.Assert 0
Resume ExitLabel
End Function
Public Sub Pause(ByVal Milliseconds As Long, _
Optional ByVal WakeMask As QueueStatusFlags = QS_ALLINPUT, _
Optional lpAbort As Long
'=========================
==========
==========
==========
==========
==========
' Pause - CPU Friendly way to pause a Task.
'=========================
==========
==========
==========
==========
==========
Dim hEvent As Long
' Sanity check.
If Milliseconds <= 0 Then Exit Function
' Create a bogus event to wait on. It will never be siganaled.
hEvent = CreateEvent(ByVal 0&, 1, 0, vbNullString)
If IsValidHandle(hEvent) Then
' Wait until timeout expires
WaitOnEvent hEvent, Milliseconds, WakeMask, lpAbort:=lpAbort
' Destroy the event
CloseHandle hEvent
Else
ApiRaise Err.LastDllError, Module, "Could not create event."
End If
End Function
Public Function WaitOnEvent( _
ByVal hEvent As Long, _
Optional ByVal TimeoutValue As Long = 15000, _
Optional ByVal WakeMask As Long = QS_ALLINPUT, _
Optional ByVal Alertable As Boolean, _
Optional ByRef WaitValue As Long, _
Optional ByVal lpAbort As Long) As Long
' Wait on the single event
WaitOnEvent = WaitOnEvents( _
VarPtr(hEvent), _
1, _
TimeoutValue, _
WakeMask, _
False, _
Alertable, _
WaitValue, _
lpAbort)
End Function
Public Function WaitOnEvents( _
ByVal lpEvents As Long, _
Optional ByVal nEvents As Long = 1, _
Optional ByVal TimeoutValue As Long = 15000, _
Optional ByVal WakeMask As Long = QS_ALLINPUT, _
Optional ByVal WaitOnAll As Boolean, _
Optional ByVal Alertable As Boolean, _
Optional ByRef WaitValue As Long, _
Optional ByVal lpAbort As Long) As Long
Const INFINITE = &HFFFFFFFF ' Infinite timeout
Const WAIT_FAILED = -1&
Const WAIT_TIMEOUT = 258& ' Wait timed out
Const WAIT_ABANDONED_0 = &H80&
Const WAIT_OBJECT_0 = 0
Const WAIT_IO_COMPLETION = &HC0& ' MsgWaitForMultipleObjectsE
x
Const MWMO_WAITALL = &H1
Const MWMO_ALERTABLE = &H2
Const MWMO_INPUTAVAILABLE = &H4
Dim EndTime As Long
Dim TimeoutTicks As Long
Dim AbortVal As Long
Dim Flags As Long
' Calculate time out value, if any supplied
If TimeoutValue > 0 Then
EndTime = timeGetTime() + TimeoutValue
Else
TimeoutTicks = INFINITE
End If
' Or in flags
If Alertable Then Flags = Flags Or MWMO_ALERTABLE
If WaitOnAll Then Flags = Flags Or MWMO_WAITALL
Do
' If an abort variable supplied...
If lpAbort <> 0 Then
' Copy contents of abort variable to local variable
CopyMemory ByVal VarPtr(AbortVal), ByVal lpAbort, 2
' Exit if the abort variable is set.
If AbortVal <> 0 Then Exit Do
End If
' Calculate # of milliseconds left before we must time out.
If TimeoutValue > 0 Then
TimeoutTicks = TickDiff(timeGetTime(), EndTime)
End If
' Wait on the supplied event
WaitValue = MsgWaitForMultipleObjectsE
x _
(nEvents, ByVal lpEvents, TimeoutTicks, WakeMask, Flags)
' Process the result
Select Case WaitValue
Case WAIT_IO_COMPLETION
' Exit a success, point to first item since we
' don't know which element completed.
WaitOnEvents = 1
Exit Do
Case WAIT_OBJECT_0 To (WAIT_OBJECT_0 + nEvents - 1), _
WAIT_ABANDONED_0 To (WAIT_ABANDONED_0 + nEvents - 1)
' Return a one-based index identifying the event that signaled
WaitOnEvents = WaitValue + 1
Exit Do
Case WAIT_TIMEOUT
' We've timed out. Exit function.
Exit Do
Case WAIT_FAILED
' There was an error. Handle probably invalid.
ApiRaise Err.LastDllError, , "Wait event(s) failed."
Case (WAIT_OBJECT_0 + nEvents)
Case Else
Debug.Assert 0
End Select
DoEvents
Loop
End Function
Public Sub ApiRaise(Optional ByVal Number As Long, _
Optional ByVal Source As String, _
Optional ByVal DescPrefix As String, _
Optional ByVal HelpFile As String, _
Optional ByVal HelpContext As Long, _
Optional ByVal NewLineCharacter As String = vbCrLf)
'=========================
==========
==========
==========
==========
==========
' ApiRaise - Builds and throws an error returned from a Win32 API call.
'
' NewLineCharacter Allows the caller to convert linefeeds to a space or
' other character. This helps when displaying log entries
' in a List that cannot display multiple lines.
'
' All other parameters are the same as Err.Raise method.
'
' NOTE: &H80070000 will be added to Number. This number represents the
' first 16 bits of an HRESULT (facility code of FACILITY_WIN32). Kudos
' to Matt Curland for this technique!
'
'=========================
==========
==========
==========
==========
==========
' Use LastDllError if no Number supplied
If Number = 0 Then
Number = Err.LastDllError
End If
' Use EXE name if no Source supplied
If Len(Source) = 0 Then
Source = App.EXEName
End If
' If a msg prefix is used then massage the message
If Len(DescPrefix) > 0 Then
' Terminate prefix with a period if not.
DescPrefix = Trim$(DescPrefix)
Select Case Right$(DescPrefix, 1)
Case ".", "?", "!"
' this case perhaps not too locale friendly
Case Else
DescPrefix = DescPrefix & "."
End Select
' Build error message and throw it
On Error GoTo 0
Err.Raise &H80070000 + Number, Source, _
DescPrefix & NewLineCharacter & LastDllErrorMsg(Number, NewLineCharacter), _
HelpFile, HelpContext
' NOTE: The Err.Raise(&H80070000 + nErr) will map the
' following Win32 errors to their VB equivilents.
'
' Win32# -> maps to ->
' -> VB# VB Error Description
' --------------------------
----------
----------
----------
----------
--
' 5 70 Permission denied
' 14 7 Out of memory
' 87 5 Invalid procedure call or argument
' 1722 462 The remote server machine does not
' exist or is unavailable
Else
' Build error message and throw it
On Error GoTo 0
Err.Raise &H80070000 + Number, Source, _
LastDllErrorMsg(Number, NewLineCharacter), _
HelpFile, HelpContext
End If
End Sub
Public Function MakeDecimal( _
ByVal HighDword As Long, _
ByVal LowDword As Long, _
Optional ByVal HighestDWord As Long, _
Optional ByVal DecimalPlaces As Byte, _
Optional ByVal Signed As Boolean) As Variant
'=========================
==========
==========
==========
==========
==========
' MakeDecimal - Convert up to three 32 bit integers into a 64 bit value.
'=========================
==========
==========
==========
==========
==========
Const DECIMAL_NEG = &H80&
Dim dec As tagDECIMAL
' NOTE: The Decimal data type uses all of the VARIANT
' structure except the 2 lead VARTYPE bytes. The Decimal
' data type is a 12 byte/96-bit value.
' Fill the decimal structure
With dec
.wReserved = VT_DECIMAL
.Lo32 = LowDword
.Mid32 = HighDword
.Hi32 = HighestDWord
Select Case DecimalPlaces
Case 0 To 28
.scale = DecimalPlaces
Case Else
Err.Raise 5
End Select
If Signed Then
.sign = DECIMAL_NEG
End If
End With
' Copy the data into return value
CopyMemory ByVal VarPtr(MakeDecimal), _
ByVal VarPtr(dec.wReserved), LenB(dec
End Function
Public Function HiDWord(ByVal vDecimal As Variant) As Long
'=========================
==========
==========
==========
==========
==========
' HiDWord - Returns the middle 32 bits of a 64 bit value [expressed as a
' Decimal or Currency within a Variant].
'
' NOTE: This function is often called when working with file system based API
' calls. For that reason we force the "value" as a Decimal/Variant. This is to
' avoid the hassle and confusion of scaling when using a Currency data type.
' The technique of using the Currency data type in place of structures like
' FILETIME and LARGE_INTEGER, et al., can be very tricky and is sometimes hard
' to tell when and why they need to be scaled and de-scaled.
'
' vDecimal The 64 bit value.
'
' RETURNS The high order DWORD of the supplied 64 bit value.
'=========================
==========
==========
==========
==========
==========
Dim dec As tagDECIMAL
' Ensure it's of the Decimal data type
Select Case VarType(vDecimal)
Case vbDecimal
' correct data type
Case vbCurrency, vbLong, vbInteger
' a valid 64 bit integer
vDecimal = CDec(vDecimal)
Case Else
' anything else would be uncivilized
Err.Raise 5
End Select
' File the DECIMAL structure
CopyMemory ByVal VarPtr(dec.wReserved), ByVal VarPtr(vDecimal), LenB(dec
HiDWord = dec.Mid32
End Function
Public Function LoDWord(ByVal vDecimal As Variant) As Long
'=========================
==========
==========
==========
==========
==========
' LoDWord - Returns the lower 32 bits of a 64 bit value [expressed as a
' Decimal or Currency within a Variant].
'
' NOTE: This function is often called when working with file system based API
' calls. For that reason we force the "value" as a Decimal/Variant. This is to
' avoid the hassle and confusion of scaling when using a Currency data type.
' The technique of using the Currency data type in place of structures like
' FILETIME and LARGE_INTEGER, et al., can be very tricky and is sometimes hard
' to tell when and why they need to be scaled and de-scaled.
'
' vDecimal The 64 bit value.
'
' RETURNS The low order DWORD of the supplied 64 bit value.
'=========================
==========
==========
==========
==========
==========
Dim dec As tagDECIMAL
' Ensure it's of the Decimal data type
Select Case VarType(vDecimal)
Case vbDecimal
' correct data type
Case vbCurrency, vbLong, vbInteger
' a valid 64 bit integer
vDecimal = CDec(vDecimal)
Case Else
' anything else would be uncivilized
Err.Raise 5
End Select
' Fill the DECIMAL structure
CopyMemory ByVal VarPtr(dec.wReserved), ByVal VarPtr(vDecimal), LenB(dec
LoDWord = dec.Lo32
End Function
Public Function HighestDWord(ByVal vDecimal As Variant) As Long
'=========================
==========
==========
==========
==========
==========
' HighestDWord - Returns the Highest 32 bits of a 64 bit value [expressed
' as a Decimal or Currency within a Variant].
'
' NOTE: This function is often called when working with file system based API
' calls. For that reason we force the "value" as a Decimal/Variant. This is to
' avoid the hassle and confusion of scaling when using a Currency data type.
' The technique of using the Currency data type in place of structures like
' FILETIME and LARGE_INTEGER, et al., can be very tricky and is sometimes hard
' to tell when and why they need to be scaled and de-scaled.
'
' vDecimal The 64 bit value.
'
' RETURNS The low order DWORD of the supplied 64 bit value.
'=========================
==========
==========
==========
==========
==========
Dim dec As tagDECIMAL
' Ensure it's of the Decimal data type
Select Case VarType(vDecimal)
Case vbDecimal
' correct data type
Case vbCurrency, vbLong, vbInteger
' a valid 64 bit integer
vDecimal = CDec(vDecimal)
Case Else
' anything else would be uncivilized
Err.Raise 5
End Select
' Fill the DECIMAL structure
CopyMemory ByVal VarPtr(dec.wReserved), ByVal VarPtr(vDecimal), LenB(dec
HighestDWord = dec.Hi32
End Function
Public Sub SplitDecimal( _
ByVal vDecimal As Variant, _
ByRef LowDword As Long, _
ByRef HighDword As Long, _
Optional ByRef HighestDWord As Long
Dim dec As tagDECIMAL
' Ensure it's of the Decimal data type
Select Case VarType(vDecimal)
Case vbDecimal
' correct data type
Case vbCurrency, vbLong, vbInteger
' a valid 64 bit integer
vDecimal = CDec(vDecimal)
Case Else
' anything else would be uncivilized
Err.Raise 5
End Select
' Fill the DECIMAL structure
CopyMemory ByVal VarPtr(dec.wReserved), ByVal VarPtr(vDecimal), LenB(dec
' Return each part of the decimal value
LowDword = dec.Lo32
HighDword = dec.Mid32
HighestDWord = dec.Hi32
End Sub
Public Function GetSafeArrayInfo(TheArray As Variant, ArrayInfo As SAFEARRAY) As Boolean
'=========================
==========
==========
==========
==========
==========
' GetSafeArrayInfo - Fills a SAFEARRAY structure for the supplied array. The
' information contained in the SAFEARRAY structure allows the caller to
' identify the number of dimensions and the number of elements for each
' dimension (among other things). Element information for each dimension is
' stored in a one-based sub-array of SAFEARRAYBOUND structures (rgsabound).
'
' TheArray The array to get information on.
' ArrayInfo The output SAFEARRAY structure.
'
' RETURNS True if the array is instantiated.
'=========================
==========
==========
==========
==========
==========
Dim lpData As Long ' Pointer to the variants data item
Dim VType As Integer ' the VARTYPE member of the VARIANT structure
' Exit if no array supplied
If Not IsArray(TheArray) Then Exit Function
With ArrayInfo
' Get the VARTYPE value from the first 2 bytes of the VARIANT structure
CopyMemory ByVal VarPtr(VType), ByVal VarPtr(TheArray), 2
' Get the pointer to the array descriptor (SAFEARRAY structure)
' NOTE: A Variant's descriptor, padding & union take up 8 bytes.
CopyMemory ByVal VarPtr(lpData), ByVal (VarPtr(TheArray) + 8), 4
' Test if lpData is a pointer or a pointer to a pointer.
If (VType And VT_BYREF) <> 0 Then
' Get real pointer to the array descriptor (SAFEARRAY structure)
CopyMemory ByVal VarPtr(lpData), ByVal lpData, 4
' This will be zero if array not dimensioned yet
If lpData = 0 Then Exit Function
End If
' Fill the SAFEARRAY structure with the array info
' NOTE: The fixed part of the SAFEARRAY structure is 16 bytes.
CopyMemory ByVal VarPtr(ArrayInfo.cDims), ByVal lpData, 16
' Ensure the array has been dimensioned before getting SAFEARRAYBOUND information
If ArrayInfo.cDims > 0 Then
' Size the array to fit the # of bounds
ReDim .rgsabound(1 To .cDims)
' Fill the SAFEARRAYBOUND structure with the array info
CopyMemory ByVal VarPtr(.rgsabound(1)), ByVal lpData + 16, ArrayInfo.cDims * Len(.rgsabound(1))
' So caller knows there is information available for the array in output SAFEARRAY
GetSafeArrayInfo = True
End If
End With
End Function
Public Function IsSomething(ByVal Object As Object) As Boolean
IsSomething = Not (Object Is Nothing
End Function
Public Sub SetControlState( _
ByVal Control As Control, _
ByVal IsEnabled As Boolean, _
Optional ByVal LockInputOnly As Boolean = True
'=========================
==========
==========
==========
==========
==========
' SetControlState - Changes the input state and appearance of a control to
' "Enabled" or "Disabled".
'=========================
==========
==========
==========
==========
==========
' Sanity check
If Control Is Nothing Then Exit Sub
Select Case TypeName(Control)
Case "Label"
' For a Label, just change the forecolor
SetControlColor Control, _
IsEnabled Or LockInputOnly
Case "TextBox", "ComboBox"
' Change Locked state & background color to match
Control.Locked = Not IsEnabled
SetControlColor Control, IsEnabled
Case "ListBox"
' Listbox doesn't have a "Locked" property.
Control.Enabled = IsEnabled Or LockInputOnly
SetControlColor Control, IsEnabled
Case "Frame", "PictureBox", "CheckBox", _
"OptionButton", "CommandButton"
' Change state of known non-input controls.
' Ignore error if "Enabled" not exported.
On Error Resume Next
Control.Enabled = IsEnabled Or LockInputOnly
Case Else
' Change state of other non-input controls
' Ignore error if "Enabled" not exported.
On Error Resume Next
Control.Enabled = IsEnabled Or LockInputOnly
End Select
End Sub
Public Sub SetControlColor(Control As Control, IsEnabled As Boolean
'=========================
==========
==========
==========
==========
==========
' SetControlColor - Changes the appearance of a control to appear
' "Enabled" or "Disabled".
'=========================
==========
==========
==========
==========
==========
Dim BackColor As OLE_COLOR
Dim ForeColor As OLE_COLOR
' Sanity check
If Control Is Nothing Then Exit Sub
Select Case TypeName(Control)
Case "Label", "Frame", "PictureBox", "CheckBox", _
"OptionButton", "CommandButton"
If IsEnabled Then
Control.ForeColor = vbWindowText
Else
Control.ForeColor = vbGrayText 'vbInactiveCaptionText
End If
Case "TextBox", "ComboBox", "ListBox"
If IsEnabled Then
Control.BackColor = vbWindowBackground
Else
Control.BackColor = vbButtonFace
End If
Case Else
If IsEnabled Then
Control.BackColor = vbWindowBackground
Else
Control.BackColor = vbButtonFace
End If
End Select
End Sub
Public Sub SetControlChildState( _
ByVal Control As Control, _
IsEnabled As Boolean, _
Optional UnNest As Boolean = True, _
Optional LockInputOnly As Boolean = True
'=========================
==========
==========
==========
==========
==========
' SetControlChildState - Changes the state of a group of controls contained
' within supplied container.
'=========================
==========
==========
==========
==========
==========
Dim Container As Object
Dim Ctl As Control
Dim hwnd As Long
' Sanity check
If Control Is Nothing Then Exit Sub
' Changes the Enabled or Locked property according to the current state.
' Also changes the Background color.
' Handle errors inline
On Error Resume Next
' loop thru each control
For Each Ctl In Control.Parent.Controls
Set Container = Ctl.Container ' save container reference
' NOTE: An error may have raised if it was a menu control,
' or some other control that doesn't export "Container" property.
If Not Container Is Nothing Then ' control has a container
' Get window handle for container
hwnd = Ctl.Container.hwnd
If hwnd = Control.hwnd Then
' it's a match
Select Case TypeName(Ctl)
Case "Frame", "PictureBox"
' These are known control containers
If UnNest Then
SetControlChildState Ctl, IsEnabled, UnNest, LockInputOnly
End If
Case Else
' If it's a child, set the state
SetControlState Ctl, IsEnabled, LockInputOnly
End Select
End If
End If
' Cleanup
Set Container = Nothing
hwnd = 0
Next Ctl
End Sub
Public Function TickDiff(ByVal TickStart As Currency, ByVal TickEnd As Currency) As Long
'=========================
==========
==========
==========
==========
==========
' TickDiff - Compares the result of two GetTickCount/timeGetTime calls and
' returns the difference. Refer to the VBA.StrComp function for implementation.
'
' This function handles such things as VB's two's complement as well as
' wrapping by the GetTickCount function.
'=========================
==========
==========
==========
==========
==========
' Handle two's complement for values larger than 2147483647&
If TickStart < 0 Then
TickStart = TickStart + CCur(2 ^ 32)
End If
' Handle two's complement AND the case where
' timeGetTime/GetTickCount wraps at (2 ^ 32 or ~49.7 days):
If TickEnd < 0 _
Or TickEnd < TickStart Then
TickEnd = TickEnd + CCur(2 ^ 32)
End If
' Return the result
TickDiff = TickEnd - TickStart
End Function
Public Function PtrToObj(ByVal lpObject As Long) As Object
Dim WeakRef As Object
On Error GoTo ErrHandler
' Get the object pointer attached to this window's user data
If Not IsValidHandle(lpObject) Then Exit Function
' Create the weak reference
Call CopyMemoryAny(WeakRef, lpObject, 4)
' Return the object reference
If Not WeakRef Is Nothing Then
Set PtrToObj = WeakRef
End If
' Kill the illegal reference
'ZeroMemory ByVal ObjPtr(WeakRef), 4
Call CopyMemoryAny(WeakRef, 0&, 4&)
Exit Function
Resume
ErrHandler:
Set PtrToObj = Nothing
Resume Next
End Function
Public Function SendMessage(hwnd As Long, wMsg As Long, wParam As Long, lParam As Long) As Long
'=========================
==========
==========
==========
==========
==========
' SendMessage - ANSI/WIDE wrapper around API function.
'=========================
==========
==========
==========
==========
==========
If IsWinNt Then ' on NT, use WIDE calls
SendMessage = SendMessageW(hwnd, wMsg, wParam, ByVal lParam) ' make the call
Else ' on Windows, use ANSI calls
SendMessage = SendMessageA(hwnd, wMsg, wParam, ByVal lParam)
End If
End Function
Public Function WNetGetUser(ByVal lpName As String, lpUserName As String, lpnLength As Long) As Long
'=========================
==========
==========
==========
==========
==========
' WNetGetUser - ANSI/WIDE wrapper. Refer to the WNet SDK.
'=========================
==========
==========
==========
==========
==========
If Len(lpName) = 0 Then lpName = vbNullString ' ensure blanks made NULL
If IsWinNt Then ' running in NT, use WIDE calls
WNetGetUser = WNetGetUserW(StrPtr(lpName
), StrPtr(lpUserName), lpnLength)
Else ' running on Win9X, use ANSI calls
WNetGetUser = WNetGetUserA(lpName, lpUserName, lpnLength)
End If
End Function
Public Function GetUserName(lpBuffer As String, nSize As Long) As Long
'=========================
==========
==========
==========
==========
==========
' GetUserName - ANSI/WIDE wrapper. Refer to the SDK.
'=========================
==========
==========
==========
==========
==========
If Len(lpBuffer) = 0 Then lpBuffer = vbNullString ' ensure blanks made NULL
If IsWinNt Then ' running in NT, use WIDE calls
GetUserName = GetUserNameW(StrPtr(lpBuff
er), nSize)
Else ' running on Win9X, use ANSI calls
GetUserName = GetUserNameA(lpBuffer, nSize)
End If
End Function
Public Function GetComputerName(lpBuffer As String, nSize As Long) As Long
'=========================
==========
==========
==========
==========
==========
' GetComputerName - ANSI/WIDE wrapper. Refer to the SDK.
'=========================
==========
==========
==========
==========
==========
If Len(lpBuffer) = 0 Then lpBuffer = vbNullString ' ensure blanks made NULL
If IsWinNt Then ' running in NT, use WIDE calls
GetComputerName = GetComputerNameW(StrPtr(lp
Buffer), nSize)
Else ' running on Win9X, use ANSI calls
GetComputerName = GetComputerNameA(lpBuffer,
nSize)
End If
End Function
Public Function SHGetPathFromIDList(ByVal Pidl As Long, ByRef pszPath As String) As Long
'=========================
==========
==========
==========
==========
==========
' SHGetPathFromIDList - ANSI/WIDE wrapper. Refer to the SDK.
'=========================
==========
==========
==========
==========
==========
If Len(pszPath) = 0 Then pszPath = vbNullString ' ensure blanks made NULL
If IsWinNt Then ' running in NT, use WIDE calls
SHGetPathFromIDList = SHGetPathFromIDListW(Pidl,
StrPtr(pszPath))
Else ' running on Win9X, use ANSI calls
SHGetPathFromIDList = SHGetPathFromIDListA(Pidl,
pszPath)
End If
End Function