troubles with API-P/Invoke again

Diablo666
06-23-2007, 12:59 PM
Hi to everyone,
I'm having troubles with a quite simple win32 api call in vb .net 2005.

Api declaration is like this:

Declare Function mciSendCommand Lib "winmm.dll" Alias "mciSendCommandA" (ByVal wDeviceID As Long, ByVal uMessage As Long, ByVal dwParam1 As Long, Byref dwParam2 As MCI_OPEN_PARMS) As Long


Constants declaration:

Public Const MCI_OPEN = &H803&
Public Const MCI_OPEN_SHAREABLE = &H100&

Structure that dwParam2 points to:

Public Structure MCI_OPEN_PARMS
Dim dwCallback As Long
Dim wDeviceID As Long
Dim lpstrDeviceType As String
Dim lpstrElementName As String
Dim lpstrAlias As String
End Structure

And here where I call the API (ok no error handling for now):

Public Function playsong()
Dim openParams As New MCI_OPEN_PARMS()
Dim lRet As Long
openParams.wDeviceID = 0
openParams.lpstrElementName = "C:\\WINDOWS\\MEDIA\\town.mid"

lRet = mciSendCommand(0, MCI_OPEN, MCI_OPEN_SHAREABLE, openParams)
Return True
End Function

I always get the error "PlatformInvokeImBalance", "A call to PInvoke function ::mciSendCommand' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature."

What I am doing wrong again?
Thanks a lot for all of your help.

OnErr0r
06-23-2007, 01:23 PM
Longs are 64 bits in vb.net. You most likely want to change them all to Integer, which is 32bits. Btw, unless you specifically need mciSendCommand, I'd go with mciSendString, which is a bit simpler.

Diablo666
06-23-2007, 04:02 PM
What a so stupid mistake! Thanks.

mcisendstring plays the file on the windows default device, but in my app i need to set different device (end user can choose if using midi port, microsoft sw sinth, or else).
So im trying to use mcisendcommand wich lets me to set the device id who will handle the output.

Now i dont get anymore the PlatformInvokeImBalance error, bust it still dont work, mcisendcommand returns error code 274.

OnErr0r
06-23-2007, 04:31 PM
hmmm... why are you escaping backslashes? That looks like code copied from a C/C++ example. Try this:

openParams.lpstrElementName = "C:\WINDOWS\MEDIA\town.mid"

If that doesn't work, provide the new declare, type and code you're using.

Diablo666
06-23-2007, 04:49 PM
Yes you are right, i've taken the declaration w example from a c++ example over the net.

Here i s a copy/paste of my module:

Module MidiFunctions1
Declare Function mciSendCommand Lib "winmm.dll" Alias "mciSendCommandA" (ByVal wDeviceID As Integer, ByVal uMessage As Integer, ByVal dwParam1 As Integer, ByRef dwParam2 As MCI_OPEN_PARMS) As Integer
Declare Function mciSendCommandPLAY Lib "winmm.dll" Alias "mciSendCommandA" (ByVal wDeviceID As Integer, ByVal uMessage As Integer, ByVal dwParam1 As Integer, ByRef dwParam2 As MCI_PLAY_PARMS) As Integer

Public Const MCI_OPEN = &H803S
Public Const MCI_OPEN_TYPE = &H2000&
Public Const MCI_OPEN_SHAREABLE = &H100&
Public Const MCI_CLOSE = &H804
Public Const MCI_PLAY = &H806S
Public Const MCI_TYPE_SEQUENCER = 523
Public Const MCI_WAIT = 2

Public Structure MCI_OPEN_PARMS
Dim dwCallback As Integer
Dim wDeviceID As Integer
Dim lpstrDeviceType As Integer
Dim lpstrElementName As String
Dim lpstrAlias As String
End Structure

Public Structure MCI_PLAY_PARMS
Dim dwCallback As Integer
Dim dwFrom As Integer
Dim dwTo As Integer
End Structure

Dim hMidiOut As Integer
Dim retval As Integer


Public Function playsong()
Dim openParams As New MCI_OPEN_PARMS()
Dim playParams As New MCI_PLAY_PARMS()
Dim lRet As Integer

openParams.wDeviceID = 0 '(add code here vith the user selected device)
openParams.lpstrDeviceType = MCI_TYPE_SEQUENCER
openParams.lpstrElementName = "C:\Windows\media\town.mid"

lRet = mciSendCommand(0, MCI_OPEN, 0, openParams)

lRet = mciSendCommandPLAY(0, MCI_PLAY, MCI_WAIT, playParams)

Return True
End Function

End Module

OnErr0r
06-23-2007, 04:56 PM
And what are the errors/returns now? Btw, doesn't dwTo need to be filled out?

Diablo666
06-23-2007, 05:11 PM
And what are the errors/returns now? Btw, doesn't dwTo need to be filled out?

First of all, thanks a lot for your support.

I don't even checked mcisendcommandplay, because i'm getting error n 273 (MCIERR_MISSING_PARAMETER) when i call "lRet = mciSendCommand(0, MCI_OPEN, 0, openParams)"


I'm trying to find out where i am wrong but with no results.
I've searched over the net tryng to understand but most of the examples about "mcisendcommand" are for vb6 or c++ for opening cd-tray.

OnErr0r
06-23-2007, 05:27 PM
The missing parameter is likely dwFlags. If you plan to pass an elementname, then mciOpenCommand must specify MCI_OPEN_ELEMENT. You might want to take a good look at the documentation: http://msdn2.microsoft.com/en-us/library/ms710950.aspx

Diablo666
06-23-2007, 06:42 PM
A very stupid mistake again!
I've read on msdn too, but then i've seen lots of examples where no flags were passed, but just a 0 or vbnull value, and that's what i've misunterstood.

The big problem is that it only accepts a device id of 0 or 1, outputting on the same device (i get the device list/id using "midiOutGetNumDevs").

When I use "midioutopen" api call, i can pass it the device identifier of which pheriperal i want to use, ant it works fine, outputting on the device i've choosen.

If there is not a manner to select the device id want to use with mcisendcommand (but it sounds strange, because the first parameter of mcisendcommand is the device id i want to use), how can i let end user to select wich device to use without having to manually edit default midi mapper in control panel - sound setup?

EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum