Auto save PDF file from Internet Explorer window using VBA - vba

I am using below code to automate saving the PDF document from Internet Explorer window. It's working fine, but I want it to be happened for multiple PDF files with multiple URL's.
When I give URL's in column A and destination path with file format as .pdf in column B by taking URL from column A and save file with file name from column B.
Option Explicit
Private Declare Function URLDownloadToFile Lib "urlmon" _
Alias "URLDownloadToFileA" ( _
ByVal pCaller As Long, _
ByVal szURL As String, _
ByVal szFileName As String, _
ByVal dwReserved As Long, _
ByVal lpfnCB As Long _
) As Long
Sub z()
Dim strSource As String
Dim strDest As String
strSource = "http://www.cran.r-project.org/doc/manuals/R-intro.pdf"
strDest = "c:\temp\blah.pdf"
URLDownloadToFile 0, strSource, strDest, 0, 0
End Sub

As #shA.t was saying, all you need to do is to wrap those lines in a For Each loop.
Solution:
Let's say, you have your URLs in A1 to A3 and your destinations in B1 to B3. Your Sub z() should look like this:
For Each source in Sheets("Sheet name").Range("A1:A3")
URLDownloadToFile 0, source.Value, source.Offset(0,1).Value, 0, 0
Next source
Explanation: For Each loops through all cell elements in range A1 to A3. In each round of the loop, source becomes that cell. Instead of hardcoding the source into your code, you can just refer to source.Value, the contents of the current cell in the loop. For the destination, you can use the .Offset method which references to a neighboring cell by its relative distance to the cell it is being called from. In this case, we want to get from A1 to B1 (and so on), i.e. zero rows down, one column right (Offset(0,1)).

Related

VBA and GetRawInputDeviceList

I am working in Access 2013 and try to get GetRawInputDeviceList, GetRawInputDeviceInfo, RegisterRawInputDevices and GetRawInputData equivalents for VBA with no success. I have also searched in vain for a procedure, function or module to get a list of connected HID devices to a computer to pick out a barcode scanner. This is the beginning of the third week so I am on my knees begging for assistance. Do any of you all have a module you're willing to share, a link to a website where this is dealt with? Any help is greatly appreciated.
Using the GetRawInputDeviceList API from VBA would be pretty tricky because of the pRawInputDeviceList parameter. Unless you're willing to jump through a ton of hoops to manage your own memory and manually handle the resulting array of RAWINPUTDEVICELIST in raw memory, you'll be better off coming at this from another direction.
Most barcode scanners I've dealt with present themselves to Windows as a keyboard. One possible solution would be to use a WMI query to enumerate attached Win32_Keyboard devices:
Private Sub ShowKeyboardInfo()
Dim WmiServer As Object
Dim ResultSet As Object
Dim Keyboard As Object
Dim Query As String
Query = "SELECT * From Win32_Keyboard"
Set WmiServer = GetObject("winmgmts:root/CIMV2")
Set ResultSet = WmiServer.ExecQuery(Query)
For Each Keyboard In ResultSet
Debug.Print Keyboard.Name & vbTab & _
Keyboard.Description & vbTab & _
Keyboard.DeviceID & vbTab & _
Keyboard.Status
Next Keyboard
End Sub
Note: If it doesn't turn up there, you can enumerate all of the USB devices by querying CIM_USBDevice: Query = "SELECT * From Win32_Keyboard"
EDIT: Per the comments, the above code won't return the handle needed to register to receive raw input events. This should get you started though - the RegisterRawInputDevices and GetRawInputData aspects are beyond the scope of what will easily go in an answer. Take a hack at it, and if you run into any problems post your code in another question.
Declarations:
Private Type RawInputDeviceList
hDevice As Long
dwType As Long
End Type
Private Type RidKeyboardInfo
cbSize As Long
dwType As Long
dwKeyboardMode As Long
dwNumberOfFunctionKeys As Long
dwNumberOfIndicators As Long
dwNumberOfKeysTotal As Long
End Type
Private Enum DeviceType
TypeMouse = 0
TypeKeyboard = 1
TypeHID = 2
End Enum
Private Enum DeviceCommand
DeviceName = &H20000007
DeviceInfo = &H2000000B
PreParseData = &H20000005
End Enum
Private Declare Function GetRawInputDeviceList Lib "user32" ( _
ByVal pRawInputDeviceList As Long, _
ByRef puiNumDevices As Long, _
ByVal cbSize As Long) As Long
Private Declare Function GetRawInputDeviceInfo Lib "user32" Alias "GetRawInputDeviceInfoW" ( _
ByVal hDevice As Long, _
ByVal uiCommand As Long, _
ByVal pData As Long, _
ByRef pcbSize As Long) As Long
Private Declare Function GetLastError Lib "kernel32" () As Long
Sample of retrieving device names with GetRawInputDeviceInfo:
Private Sub SampleCode()
Dim devices() As RawInputDeviceList
devices = GetRawInputDevices
Dim i As Long
For i = 0 To UBound(devices)
'Inspect the type - only looking for a keyboard.
If devices(i).dwType = TypeKeyboard Then
Dim buffer As String
Dim size As Long
'First call with a null pointer returns the string length in size.
If GetRawInputDeviceInfo(devices(i).hDevice, DeviceName, 0&, size) = -1 Then
Debug.Print "GetRawInputDeviceInfo error " & GetLastError()
Else
'Size the string buffer.
buffer = String(size, Chr$(0))
'The second call copies the name into the passed buffer.
If GetRawInputDeviceInfo(devices(i).hDevice, DeviceName, StrPtr(buffer), size) = -1 Then
Debug.Print "GetRawInputDeviceInfo error " & GetLastError()
Else
Debug.Print buffer
End If
End If
End If
Next i
End Sub
Private Function GetRawInputDevices() As RawInputDeviceList()
Dim devs As Long
Dim output() As RawInputDeviceList
'First call with a null pointer returns the number of devices in devs
If GetRawInputDeviceList(0&, devs, LenB(output(0))) = -1 Then
Debug.Print "GetRawInputDeviceList error " & GetLastError()
Else
'Size the output array.
ReDim output(devs - 1)
'Second call actually fills the array.
If GetRawInputDeviceList(VarPtr(output(0)), devs, LenB(output(0))) = -1 Then
Debug.Print "GetRawInputDeviceList error " & GetLastError()
Else
GetRawInputDevices = output
End If
End If
End Function
Sorry about the side scrolling.

Writing a macro that passes commands to Windows Shell

I have an Excel file containing metadata information for 20k+ images. I'm trying to write a macro that executes commands with exiftool.exe (a tool used to batch edit metadata) on Windows Shell with variables relative to each row.
For instance, I want to iterate through exiftool commands that take information from column B ("Author") such as:
C:\exiftool\exiftool.exe -Author="CELL B1 CONTENT"
C:\exiftool\exiftool.exe -Author="CELL B2 CONTENT"
...repeats ad infinitum.
This is what I've tried so far:
Sub EnterMetadata()
For Each Cell In Range("C1:C20000")
Shell("c:\Exiftool\exiftool.exe -o I:/Photos/ & ActiveCell.Offset(0, -2).Value) & " -Author=" & ActiveCell.Offset(0, -1).Value)
Next
End Sub
Notice that column A contains the path for the original files. And column B contains author names. I'm trying to retrieve information from columns A and B to use in the macro.
Untested:
Sub EnterMetadata()
Const CMD As String = "c:\Exiftool\exiftool.exe -o ""I:/Photos/{fn}"" -Author=""{auth}"""
Dim Cell as Range, s as String
For Each Cell In Range("C1:C20000")
s = Replace(CMD, "{fn}", Cell.Offset(0, -2).Value)
s = Replace(s, "{auth}", Cell.Offset(0, -1).Value)
Debug.Print s
Shell s
Next
End Sub
If any of your command line parameters might contain spaces then you should quote them (quotes are escaped in VBA strings by doubling them up)
What about using ShellExecute?
This is what you need to declare in your macro so you can use it:
Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" ( _
ByVal hWnd As Long, _
ByVal lpOperation As String, _
ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, _
ByVal nShowCmd As Long) As Long
You can pass parameters to it as String (lpParameters), get a return value tohelp understand what happened if something went wrong and is generally more versatile than using Shell.
You can do something similar to this (this is not tested, as I don't have exiftool.):
ShellExecute 0, vbNullString, "C:\exiftool\exiftool.exe", "-Author=""CELL B1 CONTENT""", vbNullString, 10 ' 10=SW_SHOWDEFAULT
I'll let you populate the author according to your requirements.
For full information about ShellExecute, click here to have a look on MSDN.

Round Image from Worksheet UserForm Excel

I was wondering if it was possible to display the below image as it looks (Circular) on an Excel Userform:
Picture http://im82.gulfup.com/E7phxt.png
Or at least I would like to display to maintain the transparency of the image, as it would appear that the Picture Frame does not accept the PNG format.
Userform http://im75.gulfup.com/LJj6ES.png
My second and bigger problem is that I would like to load the images into the UserForm directly from the excel worksheet "Sheet1" where I named the images that I have inserted as: usflag, canadaflag, mexicoflag, etc.....
Excel http://im75.gulfup.com/1uJ8cg.png
The reason for doing this is that the sheet will be shared and I do not want to link the picture paths to a particular folder that will have to shared along with the sheet.
Help will be highly appreciated.
I have such a solution in place. The image background in the form is not really transparent. The image in the Excel sheet is a PNG with a transparent background sitting on a colored Excel cell fill and is then copied into the userform. Here goes:
Load the images into Excel.
Set the Sheet background to your desired color, i.e. the color you use in the userform.
select a rectangular range that includes one of your globe and use "Copy as picture"
Paste into your spreadsheet and change its name from Picture 1 to SelectedFlag
Create a range name called PictureSource and assign it the range you previously selected for the image
Select the pasted image and in the formula bar type a = sign followed by the range name PictureSource
you can now create some logic (either in VBA or with a dynamic range name formula) that changes the reference for PictureSource when a specific condition is met, e.g. when a country field has a specific value. Test that this works, i.e. if you run the VBA or if you change a specific cell value, the image shown in SelectedFlag changes.
all the above happen on the worksheet called "TheHiddenSheet"
On your userform, insert an image control of the desired dimensions and let its name be Image1
use some code when the form is initialized to copy the image from the hidden sheet and paste it over Image1 of the form.
This is the code I use
Private Sub UserForm_Initialize()
Worksheets("TheHiddenSheet").Shapes("SelectedFlag").Copy
Set Image1.Picture = PastePicture()
End Sub
The PastePicture() command is not a native Excel function, but a piece of code by Steve Bullen. You need to create a regular module and paste the following code there:
'*--------------------------------
'*
'* MODULE NAME: Paste Picture
'* AUTHOR & DATE: STEPHEN BULLEN, Office Automation Ltd
'* 15 November 1998
'*
'* CONTACT: Stephen#oaltd.co.uk
'* WEB SITE: http://www.oaltd.co.uk
'*
'* DESCRIPTION: Creates a standard Picture object from whatever is on the clipboard.
'* This object can then be assigned to (for example) and Image control
'* on a userform. The PastePicture function takes an optional argument of
'* the picture type - xlBitmap or xlPicture.
'*
'* The code requires a reference to the "OLE Automation" type library
'*
'* The code in this module has been derived from a number of sources
'* discovered on MSDN.
'*
'* To use it, just copy this module into your project, then you can use:
'* Set Image1.Picture = PastePicture(xlPicture)
'* to paste a picture of whatever is on the clipboard into a standard image control.
'*
'* PROCEDURES:
'* PastePicture The entry point for the routine
'* CreatePicture Private function to convert a bitmap or metafile handle to an OLE reference
'* fnOLEError Get the error text for an OLE error code
'*----------------------------
Option Explicit
Option Compare Text
'----------------------------
' User-Defined Types for API Calls '
'----------------------------
'Declare the GUID Type structure for the IPicture OLE Interface
Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
'Declare the Picture Description Type structure
Private Type PICTDESC
Size As Long
Type As Long
hPic As Long 'Holds the handle to a .bmp, .emf, .ico, .wmf file
Data1 As Long 'For a .bmp this holds the pallete handle hPal. For a .wmf this hold the xExt value.
Data2 As Long 'Used only with a .wmf to hold the yExt value.
End Type
'----------------------------
' Windows API Function Declarations '
'----------------------------
'Does the clipboard contain a bitmap/metafile?
Private Declare Function IsClipboardFormatAvailable _
Lib "user32.dll" _
(ByVal wFormat As Integer) _
As Long
'Open the clipboard to read and write data
Private Declare Function OpenClipboard _
Lib "user32.dll" _
(ByVal hWnd As Long) _
As Long
'Get a pointer to the bitmap/metafile
Private Declare Function GetClipboardData _
Lib "user32.dll" _
(ByVal wFormat As Integer) _
As Long
'Copy data to the clipboard
Private Declare Function SetClipboardData _
Lib "user32.dll" _
(ByVal uFormat As Long, _
ByVal hData As Long) _
As Long
'Empty the clipboard
Private Declare Function EmptyClipboard _
Lib "user32.dll" () As Long
'Close the clipboard
Private Declare Function CloseClipboard _
Lib "user32.dll" () As Long
'Convert the handle into an OLE IPicture interface.
Private Declare Function OleCreatePictureIndirect _
Lib "olepro32.dll" _
(ByRef pPictDesc As PICTDESC, _
ByRef riid As GUID, _
ByVal fOwn As Long, _
ByRef ppvObj As IPicture) _
As Long
'Create our own copy of the metafile, so it doesn't get wiped out by subsequent clipboard updates.
Declare Function CopyEnhMetaFile _
Lib "GDI32.dll" Alias "CopyEnhMetaFileA" _
(ByVal hemfSrc As Long, _
ByVal lpszFile As String) _
As Long
'Create our own copy of the bitmap, so it doesn't get wiped out by subsequent clipboard updates.
Declare Function CopyImage _
Lib "user32.dll" _
(ByVal hImage As Long, _
ByVal uType As Long, _
ByVal cxDesired As Long, _
ByVal cyDesired As Long, _
ByVal fuFlags As Long) _
As Long
'The API Constants needed
Const CF_BITMAP = &H2
Const CF_ENHMETAFILE = &HE
Const CF_METAFILEPICT = &H3
Const CF_PALETTE = &H9
Const IMAGE_BITMAP = &H0
Const IMAGE_ICON = &H1
Const IMAGE_CURSOR = &H2
Const LR_COPYRETURNORG = &H4
Public Function PastePicture(Optional xlPicType As Long = xlPicture) As IPicture
'Some pointers
Dim hClip As Long
Dim hCopy As Long
Dim hObj As Long
Dim hPal As Long
Dim hPicAvail As Long
Dim PicType As Long
Dim RetVal As Long
'Convert the Excel picture type constant to the correct API constant
PicType = IIf(xlPicType = xlBitmap, CF_BITMAP, CF_ENHMETAFILE)
'Check if the clipboard contains the required format
hPicAvail = IsClipboardFormatAvailable(PicType)
If hPicAvail <> 0 Then
'Get access to the clipboard
hClip = OpenClipboard(0&)
If hClip > 0 Then
'Get a handle to the object
hObj = GetClipboardData(PicType)
'Create a copy of the clipboard image in the appropriate format.
If PicType = CF_BITMAP Then
hCopy = CopyImage(hObj, IMAGE_BITMAP, 0&, 0&, LR_COPYRETURNORG)
Else
hCopy = CopyEnhMetaFile(hObj, vbNullString)
End If
'Release the clipboard to other programs
RetVal = CloseClipboard
'If there is a handle to the image, convert it into a Picture object and return it
If hObj <> 0 Then Set PastePicture = CreatePicture(hCopy, 0, PicType)
End If
End If
End Function
Private Function CreatePicture(ByVal hPic As Long, ByVal hPal As Long, ByVal PicType) As IPicture
'IPicture requires a reference to "OLE Automation"
Dim Ref_ID As GUID
Dim IPic As IPicture
Dim PicInfo As PICTDESC
Dim RetVal As Long
'OLE Picture types
Const PICTYPE_UNINITIALIZED = -1
Const PICTYPE_NONE = 0
Const PICTYPE_BITMAP = 1
Const PICTYPE_METAFILE = 2
Const PICTYPE_ICON = 3
Const PICTYPE_ENHMETAFILE = 4
'Create a UDT to hold the reference to the interface ID (riid).
'IPicture GUID {7BF80980-BF32-101A-8BBB-00AA00300CAB}
'StdPicture GUID {0BE35204-8F91-11CE-9DE3-00AA004BB851}
With Ref_ID
.Data1 = &H7BF80980
.Data2 = &HBF32
.Data3 = &H101A
.Data4(0) = &H8B
.Data4(1) = &HBB
.Data4(2) = &H0
.Data4(3) = &HAA
.Data4(4) = &H0
.Data4(5) = &H30
.Data4(6) = &HC
.Data4(7) = &HAB
End With
'Fill PicInfo structure
With PicInfo
.Size = Len(PicInfo) ' Length of structure.
.Type = IIf(PicType = CF_BITMAP, PICTYPE_BITMAP, PICTYPE_ENHMETAFILE) ' Type of Picture
.hPic = hPic ' Handle to image.
.Data1 = IIf(PicType = CF_BITMAP, hPal, 0&) ' Handle to palette (if bitmap).
.Data2 = 0&
End With
'Create the Picture object.
RetVal = OleCreatePictureIndirect(PicInfo, Ref_ID, True, IPic)
'Check if an error ocurred
If RetVal <> 0 Then
MsgBox "Create Picture Failed - " & GetErrMsg(RetVal)
Set IPic = Nothing
Exit Function
End If
'Return the new Picture object.
Set CreatePicture = IPic
End Function
Private Function GetErrMsg(ErrNum As Long) As String
'OLECreatePictureIndirect return values
Const E_ABORT = &H80004004
Const E_ACCESSDENIED = &H80070005
Const E_FAIL = &H80004005
Const E_HANDLE = &H80070006
Const E_INVALIDARG = &H80070057
Const E_NOINTERFACE = &H80004002
Const E_NOTIMPL = &H80004001
Const E_OUTOFMEMORY = &H8007000E
Const E_POINTER = &H80004003
Const E_UNEXPECTED = &H8000FFFF
Select Case ErrNum
Case E_ABORT
GetErrMsg = " Aborted"
Case E_ACCESSDENIED
GetErrMsg = " Access Denied"
Case E_FAIL
GetErrMsg = " General Failure"
Case E_HANDLE
GetErrMsg = " Bad/Missing Handle"
Case E_INVALIDARG
GetErrMsg = " Invalid Argument"
Case E_NOINTERFACE
GetErrMsg = " No Interface"
Case E_NOTIMPL
GetErrMsg = " Not Implemented"
Case E_OUTOFMEMORY
GetErrMsg = " Out of Memory"
Case E_POINTER
GetErrMsg = " Invalid Pointer"
Case E_UNEXPECTED
GetErrMsg = " Unknown Error"
End Select
End Function
You will need to establish some kind of logic that determines which flag/picture should be shown. Let's assume in cell A1 in the worksheet you store the name of the country, i.e. either USA, Canada, Argentina or Mexico.
Make sure all your flag pictures are on a cell background where the range you need to select to capture the picture is always the same size. Now, select the range that contains the US flag and assign it the range name "USA". Select the range that contains the Canadian flag and assign it the range name "Canada". Rinse and repeat for Argentina and Mexico.
So now, you have four range names, one for each flag. Depending on the value of cell A1 you can now change the picture that is showing in the "SelectedFlag" image. Remember that this image is linked to a named range called "PictureSource". You can now re-define the reference for that range and make it dynamic.
Edit the named range PictureSource and change its definition to
=INDIRECT(Sheet1!$A$1)
This will of course require that the values in A1 and the named ranges are perfect matches. Whenever the value in A1 is changed, the dynamic image will change as well. Here is a screenshot of such a scenario with three different images.
So, before the form is loaded, or while the form is loading, you need to have some activity that sets cell A1 to the desired country name.
Never mind I figured it out.
Since Excel VBA wouldn't allow me to import PNG images without a background to seems as round, I just edited the background color in Photoshop to match the color of the User Interface.
Now once I import it it seems as though the image background is transparent and hence appears round.

Reading/Writing INI w/ variable Section Name

Good afternoon folks -
I'm working on reading/writing an external file that is created and managed by a 3rd party that uses .INI structured files as its scripting language. I've got a wrapper working pretty well however, the section names are static with a unique number at the end ([GENERAL-1]) so that you have have the same task more than once. I am using VB.NET w/ VS2008.
My code below can successfully read a key from a section that is hardcoded but I'd like the key to be generic.
INI
test.ini
[GENERAL-1]
SUPPRESSTASKERRORS=Y
TASKERRORSENDJOB=Y
Code:
Declare Function GetPrivateProfileString Lib "kernel32.dll" Alias
"GetPrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As
String, ByVal lpDefault As String, ByVal lpReturnedString As String, ByVal nSize As
Long, ByVal lpFileName As String) As Long
Declare Function WriteProfileString Lib "kernel32.dll" Alias
"WritePrivateProfileStringA" (ByVal lpApplicationName As String, ByVal lpKeyName As
String, ByVal lpString As String, ByVal lpFileName As String) As Long
' Read INI file
Dim uname As String ' receives the value read from the INI file
Dim slength As Long ' receives length of the returned string
Dim OriginalMJB As String = "c:\test\test.ini"
uname = Space(1024)
slength = GetPrivateProfileString("General-1", "SUPPRESSTASKERRORS", "anonymous",
uname, 1024, OriginalMJB)
Notice the General-1 above, if I have the value hardcoded as -1 I can read the input .ini file without a problem. Any thoughts on how I can get and use the value left of the hyphen?
Any help is appreciated!
--George
Here's one way. From here you should be able to make SectionNo equal the specific section you want.
Dim section As String = "General"
Dim SectionNo as String = "-"
Dim Number as Integer = 1
SectionNo += Number.ToString
slength = GetPrivateProfileString(section + SectionNo, "SUPPRESSTASKERRORS", "anonymous", uname, 1024, OriginalMJB)
Here's a couple of options
Dim SectionName As String = "General-1"
Dim SectionCategorie As String = ""
Dim Section As String = ""
'Using Split - It returns an array so you can load the results into an array
'or just call it and load the specific index each time.
SectionCategorie = Split(SectionName, "-")(0)
Section = Split(SectionName, "-")(1)
'Using Substring
SectionCategorie = SectionName.Substring(0, SectionName.IndexOf("-"))
Section = SectionName.Substring(SectionName.IndexOf("-") + 1)

mciSendString/winmm.dll - Playing an Audio file

I am working on a program in Visual Basic 2008, I am required to have different types of sounds with varying volumes. Hence My.Computer.Audio.Play is not a valid option.
I decided to use mciSendString instead and found the following code
Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" _
(ByVal lpstrCommand As String, ByVal lpstrReturnString As String, _
ByVal uReturnLength As Integer, ByVal hwndCallback As Integer) As Integer
mciSendString("close myWAV", Nothing, 0, 0)
Dim fileName1 As String =
mciSendString("open " & fileName1 & " type mpegvideo alias myWAV", Nothing, 0, 0)
mciSendString("play myWAV", Nothing, 0, 0)
'min Volume is 1, max Volume is 1000
Dim Volume As Integer = (SFXVolume * 100)
mciSendString("setaudio myWAV volume to " & Volume, Nothing, 0, 0)
Now this code I have tested and is working perfectly when filename1 = "C://Correct.wav"
However when I use
filename1 = My.Application.Info.DirectoryPath & "\Correct.wav"
I get no sound play whatsoever.
Could anyone please help me correct my code so that this works.
Thank you in advance.
If your DirectoryPath has spaces then mciSendString won't be able to recognize the command accurately, you need to surround the path with quotes:
mciSendString(
String.Format("open ""{0}"" type mpegvideo alias myWAV", fileName1), Nothing, 0, 0)
Be sure to check returned status as well, as Hans suggests.
Also, since you don't know whether DirectoryPath has a trailing backslash or not, the accurate way to produce full path from directory and name is:
fileName1 = System.IO.Path.Combine(My.Application.Info.DirectoryPath, "Correct.wav")
Use Private Declare Function SetCurrentDirectory Lib "kernel32" Alias "SetCurrentDirectoryA" (ByVal lpPathName As String) As Long then SetCurrentDirectory filepath before opening file for play. That is working for me.
You need to use the DLL Call GetShortPathName in order to pass file paths to WINMM.DLL.
lpszLongPath is your full path string, and the short pathname will be passed to lpszShortPath.
cchbuffer should really be set to 200 or so, though in most cases, the returned string will be much shorter. You should use a VB padded string.
Private Declare Function GetShortPathName Lib "kernel32" Alias "GetShortPathNameA" (ByVal lpszLongPath As String, ByVal lpszShortPath As String, ByVal cchBuffer As Long) As Long
I have just used the mciSendString calls in a batch midi-file reading programme, opening 3642 midi files and returning copyright, title and play duration strings actually quite quickly!
Best Regards
David R Leach