none
MCI Commands - Updating VB6 code to VB.NET RRS feed

  • Question

  • The code I am using is from a VB6 Class modal. It works fine in that old project. I am now converting to VB.NET using the Visual Studio 2017 IDE. I am frustrated as I can not get the connection to work and do not know why, and I don't know how to read the error code that is returned as none of the MCI commands see to work. Any suggestions are welcome. Here is the relevant code from a class module in the project:

    Public Class MMedia

        Friend Shared msAlias As String       'Local name of the multimedia resource
        Friend Shared msFilename As String  'Holds the filename
        Friend Shared msLength As Single   'length of the filename
        Friend Shared msPosition As Single  'current position in file
        Friend Shared msStatus As String  'current status as a string
        Friend Shared mbWait As Boolean    'Determines if VB should wait until play is complete before returning.

        '------------ API DECLARATIONS ---------------------------------------------
        Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" _
        (ByVal lpstrCommand As String, ByVal lpstrReturnString As String,
            ByVal uReturmsLength As Long, ByVal hwndCallback As Long) As Long

        Private Declare Function mciGetErrorString Lib "winmm.dll" Alias "mciGetErrorStringA" _
        (ByVal fdwError As Long, ByVal lpszErrorText As String, ByVal cchErrorText As Long) As Boolean '

        Private Declare Function mciGetDeviceID Lib "winmm.dll" Alias "mciGetDeviceIDA" _
        (ByVal lpszDevice As String) As Integer

        Private Declare Function midiOutGetNumDevs Lib "winmm.dll" () As Integer

    Public Sub mmOpen(ByVal sTheFile As String)
            Dim nReturn As Long
            Dim sType As String
            Dim sMessage As String = ""
            Dim sError As String
            Dim iDeviceID As Integer

            msAlias = Alb.MidiSource 'See notes

            ' Determine the type of file from the file extension
            Select Case Strings.UCase(Strings.Right(sTheFile, 3))
                Case "WAV"
                    sType = "Waveaudio"
                Case "AVI"
                    sType = "AviVideo"
                Case "MID"
                    sType = "Sequencer"
                Case Else 'not known
                    Exit Sub
            End Select

            ' If the name contains a space we have to enclose it in quotes
            If Strings.InStr(sTheFile, " ") Then sTheFile = Chr(34) & sTheFile & Chr(34)
            nReturn = mciSendString("Open " & sTheFile & " ALIAS " & msAlias _
                  & " TYPE " & sType & " wait", "", 0, 0)

            sError = mciGetErrorString(nReturn, sMessage, 128)
            sError = dhMCIError(nReturn)
            If sMessage = "" Then sMessage = "Error unknown"
            If nReturn = 0 Then sMessage = ""  'add ErrorTrap


            'Get device ID
            iDeviceID = mciGetDeviceID(msAlias)  ' ############ Tells what current device ID# is
            If iDeviceID = 0 Then msAlias = "" ' File did not open
            Console.WriteLine("Midi Device " & iDeviceID, " opened as " & msAlias)


            mdiAlberta.lstDetails.Items.Add("Midi Player open on Device # " & iDeviceID & " = " & msAlias)
            Console.WriteLine(" Error code = " & nReturn & "  Msg: " & sError)

        End Sub

    The "sTheFile" string is the file that is opened using the OpenFileDialog method. In this case it will look like:

    "C:\Users\Curmudgeon\Documents\Midi Song Files\Boogie Woogie Piano Track.mid"   

    The midi file is decoded in the project and then I attempt to open the file in the MMplayer. This all worked fine in VB6. The nReturn result when I attempt to open the player is a numerical string. Example: 66991044457136397

    I don't know how to read that code and I do not have any luck using the   sError = mciGetErrorString(nReturn, sMessage, 128)

    method. Can anyone help me here? Thanks in advance.

    Monday, November 11, 2019 7:09 PM

Answers

  • Hi Sam,

    This is really good info. A lot is different in .NET so I have a lot to learn. I really appreciate the response and this info.

    Friday, November 15, 2019 9:23 PM

All replies

  • Those declarations are wrong.

    For example :

        <DllImport("Winmm.dll", SetLastError:=True)>
        Private Shared Function mciSendString(ByVal command As String, ByVal buffer As StringBuilder, ByVal bufferSize As Integer, ByVal hwndCallback As IntPtr) As Integer
        End Function
    
        <DllImport("Winmm.dll", SetLastError:=True)>
        Private Shared Function mciGetErrorString(ByVal fdwError As Integer, ByVal lpszErrorText As StringBuilder, ByVal cchErrorText As Integer) As Boolean
        End Function

    Then

        nReturn = mciSendString("Open " & sTheFile & " ALIAS " & msAlias _
              & " TYPE " & sType & " wait", Nothing, 0, 0)
        Dim sbMessage As StringBuilder = New StringBuilder(256)
        Dim bReturn As Boolean = mciGetErrorString(nReturn, sbMessage, sbMessage.Capacity)
        ' etc...


    Monday, November 11, 2019 7:42 PM
  • The midi file is decoded in the project and then I attempt to open the file in the MMplayer. This all worked fine in VB6. The nReturn result when I attempt to open the player is a numerical string. Example: 66991044457136397

    Unless you are using the OpenFileDialog.OpenFile Method you probably are not opening the file. You do not say or show much more about that so we cannot know if that is a problem.

    See mciSendString function. The error code is the low-order word. You need to pass only the low-order word (2 bytes). So for 66991044457136397 it is 269. Do you know how to get just the low-order word?



    Sam Hobbs
    SimpleSamples.Info

    Monday, November 11, 2019 8:00 PM
  • Hi Castorix31,

    I really appreciate your help. As you can see I am a hack but I love doing it. I have searched everywhere for documentation on the MM PLayer specification but to no success. I will give this a shot.

    Thank You!

    Tuesday, November 12, 2019 6:39 PM
  • Hi Sam,

    I think I read that the return is two words at 4 bytes each. I do not know how to identify each word, and then select the "low" order word. Finally, how to get 269 from that.

    Finally, even if I can extract the code correctly, I can find no documentation of the meanings. I will take any info you can pass along.

    Thanks for your help.

    Tuesday, November 12, 2019 6:44 PM
  • Hey Castorix31,

    I have only been using VS2017 for a couple months and a lot of it is still confusing. Do I paste that with the function directly into the module as you have presented to me? I am getting an error BC30455 that says "Argument not specified for parameter 'SetLastError' of 'Public Sub New(v as string, SetLastError as Boolean)'.

    Additionally BC30389  'DllImportAttribute.SetLastError' is not accessible in this context because it is private.

    Thanks


    Tuesday, November 12, 2019 9:34 PM
  • The following shows the conversion.

    Dim nReturn As Long = 66991044457136397
    Console.WriteLine(nReturn And &Hffff)
    

    In other words, just use nReturn And &Hffff to get the error code.

    The meaning of the error codes are totally documented but the documentation is intended for C++ programmers. The mciSendString function documentation links to macro names, such as MCIERR_BAD_TIME_FORMAT, for the error codes. You need to find the macro definitions, as in:

    #define MCIERR_BASE            256
    .
    .
    .
    #define MCIERR_INVALID_DEVICE_ID        (MCIERR_BASE + 1)
    

    Those are in separate files but you can use Find in Files in VS to find the relevant files. I hope you can find the #include directories folder.

    So 269 (269-256=13) is MCIERR_MISSING_STRING_ARGUMENT.



    Sam Hobbs
    SimpleSamples.Info

    Tuesday, November 12, 2019 9:36 PM
  • Hi Sam,

    This is really good info. A lot is different in .NET so I have a lot to learn. I really appreciate the response and this info.

    Friday, November 15, 2019 9:23 PM