szPname As String * MAXPNAMELEN (How to declare)

  • Thread starter Sakharam Phapale
  • Start date
S

Sakharam Phapale

Hi All,
How to declare the following statement in following structure.

szPname As String * MAXPNAMELEN


Public Structure MIXERCAPS
public wMid As Integer
public wPid As Integer
public vDriverVersion As Long
public szPname As String * MAXPNAMELEN
public fdwSupport As Long
public cDestinations As Long
End Structure

Thanks and Regards.
Sakharam Phapale.
 
T

Tom Shelton

Hi All,
How to declare the following statement in following structure.

szPname As String * MAXPNAMELEN


Public Structure MIXERCAPS
public wMid As Integer
public wPid As Integer
public vDriverVersion As Long
public szPname As String * MAXPNAMELEN
public fdwSupport As Long
public cDestinations As Long
End Structure

Thanks and Regards.
Sakharam Phapale.

Looking at the MSDN docs now...... Ok:

' Replace XX with correct value...
Public Const MAXPNAMELEN As Integer = XX

<StructLayout (LayoutKind.Sequential, CharSet := CharSet.Auto)> _
Public Structure MIXERCAPS
Public wMid As Short
Public wPid As Short

' You'll have to see what type MMVERSION really is,
' but from the description it sounds like a 2-byte integer
' also known as a WORD in API speak and a Short in VB.NET
Public vDriverVersion As Short

<MarshalAs (UnmanagedType.ByValTStr, SizeConst := MAXPNAMELEN)>
Public szPname As String

Public fdwSupport As Integer
Public cDestinations As Integer
End Structure

Be aware that VB6 declarations are not going to be valid for most API
calls. Data types have changed size. Here is a small table to sum up
the differences:

Data Type VB6 Size VB.NET Size
___________________________________
Byte 8-bit 8-bit
Short N/A 16-bit (same size as VB6 Integer)
Integer 16-bit 32-bit
Long 32-bit 64-bit

So, basically when calling api calls from VB.NET - use Short where you
used integer in VB6 and Integer where you used Long. You can use Long
where you would have used Currency in VB6.

Also, notice the CharSet attribute on the structure. This is done so
that it will be converted to the proper charset for the current
platform. This eliminates a lot of the problems with calling API calls
in VB6 - you couldn't call Unicode functions, at least not with out some
hacks :) To use this structure in the function, the CharSet attribute
will have to be set there as well - but VB.NET Declare has a way of
handling that (I'm going to assume your using mixerGetDevCaps)...

Public Declare Auto Function mixerGetDevCaps Lib "winmm.dll" _
(ByVal uMxId As System.IntPtr, _
ByRef pmxcaps As MIXERCAPS, _
ByVal cbmxcaps As Integer) As Integer


By using the Auto clause of the declare statement we avoid having to
alias this function to the A version, because the runtime will call the
function most appropriate to the current platform - which is the W
version on NT based OS's.
 
S

Sakharam Phapale

Hi Tom,

I am using the structure "MIXERLINE" which includes structure "TARGET".
I have used following statement
mxl.cbStruct = Len(mxl)

This should gives me 168 as length of structure mxl which is "MixerLine"
type, but it gives me 68. It doesn't include the string variables.

What is the reason?

I am also using following API function which fills detail of mixer control
in mxl structure which includs short and full name.

ret = mixerGetLineInfo(hMixer, mxl, MIXER_GETLINEINFOF_COMPONENTTYPE)

ret comes as 11. Above function doesn't work.



<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _

Public Structure Target

Public dwType As Integer

Public dwDeviceID As Integer

Public wMid As Integer

Public wPid As Int16

Public vDriverVersion As Int16

<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAXPNAMELEN)> _

Public szPname As String

End Structure



<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _

Public Structure MIXERLINE

Public cbStruct As Integer

Public dwDestination As Integer

Public dwSource As Integer

Public dwLineID As Integer

Public fdwLine As Integer

Public dwUser As Integer

Public dwComponentType As Integer

Public cChannels As Integer

Public cConnections As Integer

Public cControls As Integer

<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MIXER_SHORT_NAME_CHARS)> _

Public szShortName As String

<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MIXER_LONG_NAME_CHARS)> _

Public szName As String

Public tTarget As Target

End Structure


Waiting for your respose.

Thanks

Sakharam Phapale
 
T

Tom Shelton

Hi Tom,

I am using the structure "MIXERLINE" which includes structure "TARGET".
I have used following statement
mxl.cbStruct = Len(mxl)

This should gives me 168 as length of structure mxl which is "MixerLine"
type, but it gives me 68. It doesn't include the string variables.

What is the reason?

User Marshal.SizeOf... This will give you the marshaled length, instead
of the .NET length. (Does that makes sense?)
I am also using following API function which fills detail of mixer control
in mxl structure which includs short and full name.

ret = mixerGetLineInfo(hMixer, mxl, MIXER_GETLINEINFOF_COMPONENTTYPE)

ret comes as 11. Above function doesn't work.

Are you declaring mixerGetLineInfo correctly? Should probably be:

Public Declare Auto Function mixerGetLineInfo Lib "winmm.dll" _
(ByVal hmxobj As System.IntPtr, _
ByRef pmxl As MIXERLINE, _
ByVal fdwInfo As Integer) As Integer
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _

Public Structure Target

Public dwType As Integer

Public dwDeviceID As Integer

Public wMid As Integer

Public wPid As Int16

Public vDriverVersion As Int16

<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAXPNAMELEN)> _

Public szPname As String

End Structure

According to MSDN, your wMid should also be Short or Int16. I would
also verify the MMVERSION type - I'm assuming Int16 from the docs, but
you never know...
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _

Public Structure MIXERLINE

Public cbStruct As Integer

Public dwDestination As Integer

Public dwSource As Integer

Public dwLineID As Integer

Public fdwLine As Integer

Public dwUser As Integer

Public dwComponentType As Integer

Public cChannels As Integer

Public cConnections As Integer

Public cControls As Integer

<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MIXER_SHORT_NAME_CHARS)> _

Public szShortName As String

<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MIXER_LONG_NAME_CHARS)> _

Public szName As String

Public tTarget As Target

End Structure


Waiting for your respose.

Thanks

Sakharam Phapale

The rest looks ok at first glance...
 
S

Sakharam Phapale

Hi Tom,

Thanks for your reply. I have another query related to this.
I am using GlobalAlloc API to allocate memeory for structure "MIXERCONTROL"
And then I used following API function to get the mixer control iformation.
mixerGetLineControls(hMixer, mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE)

Everyhing goes right upto above statement.

Now I want to fill the allocated strucure by the pointer which returned by
above API function.

For that, I used API function CopyStructFromPtr(........)
Calling this function resulted application to crash without giving any
error.
I tried lot but I don't understand why?
Since the same code runs in VB6.0. well I am not been able to convert it to
..NET

Any Help will be really appriciated.

Thanks & Regards
Sakharam Phapale
 
T

Tom Shelton

Hi Tom,

Thanks for your reply. I have another query related to this.
I am using GlobalAlloc API to allocate memeory for structure "MIXERCONTROL"
And then I used following API function to get the mixer control iformation.
mixerGetLineControls(hMixer, mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE)

Everyhing goes right upto above statement.

Now I want to fill the allocated strucure by the pointer which returned by
above API function.

For that, I used API function CopyStructFromPtr(........)
Calling this function resulted application to crash without giving any
error.
I tried lot but I don't understand why?
Since the same code runs in VB6.0. well I am not been able to convert it to
.NET

Any Help will be really appriciated.

Thanks & Regards
Sakharam Phapale

1. You don't need to use GlobalAlloc and GlobalFree. You can use the
equivalent Marshal methods - Marshal.AllocHGlobal and
Marshal.FreeHGlobal.

2. Don't use RtlMoveMemory (or it's various alliases). Your going to
get your self in trouble if you don't jump through the necessary hoops -
like pinning the object references, etc... In your case, if I
understand what your trying to accomplish (though, looking at the VB6
code you're trying to convert would be helpful) - I would say that
Marshal again comes to your rescue, with it's PtrToStructure method...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top