VB .net conversion of VB 6's "String * 32" ability

  • Thread starter Thread starter Ian Rutherford
  • Start date Start date
I

Ian Rutherford

Heya guys,
It seems VB .net no longer supports the awesome ability of VB 6 to declare
something as a string and specify how long the string would be all in one
line:
Public myString as String * 32 'this would make it 32 characters long

Apparently the VB .net conversion is to do this:
Public myString as String
myString = new String(CChar(" "), 32) 'this creates a string with
32 blank spots in it

My problem lies in these facts:
a) You can't use this technique in Structures, which is where I absolutely
must use it.
b) Trying to say Public svDevice = new String(CChar(" "), 32) results in
VB saying that "svDevice" needs to be a constant for this to be allowed.
Unfortunately, I can't set this to a const because it needs to be changed.

Background:
I'm calling from the Windows GDI Platform SDK this: Private Declare
Function GetMonitorInfo Lib "User32.dll" Alias "GetMonitorInfoA" (ByVal
hMonitor As Integer, ByRef lpMI As MonitorInfoEx) As Integer
and the Structure that I have to hold each monitor's info is:

Private Structure MonitorInfoEx
Public cbSize As Integer
Public rcMonitor As RectAPI
Public rcWork As RectAPI
Public dwFlags As Integer
Public szDevice As String <<=== that has to be 32 characters long
End Structure

So basically, because VB .net doesn't support String-length pre-defining the
way I need it to, I can't use GetMonitorInfo or anything like it. Does
anyone know of this problem and how I can work around it? Thanks!!!

Ian
 
* "Ian Rutherford said:
something as a string and specify how long the string would be all in one
line:
Public myString as String * 32 'this would make it 32 characters long

Have a look at 'VBFixedStringAttribute' in the documentation.
 
Heya guys,
It seems VB .net no longer supports the awesome ability of VB 6 to declare
something as a string and specify how long the string would be all in one
line:
Public myString as String * 32 'this would make it 32 characters long

Apparently the VB .net conversion is to do this:
Public myString as String
myString = new String(CChar(" "), 32) 'this creates a string with
32 blank spots in it

My problem lies in these facts:
a) You can't use this technique in Structures, which is where I absolutely
must use it.
b) Trying to say Public svDevice = new String(CChar(" "), 32) results in
VB saying that "svDevice" needs to be a constant for this to be allowed.
Unfortunately, I can't set this to a const because it needs to be changed.

Background:
I'm calling from the Windows GDI Platform SDK this: Private Declare
Function GetMonitorInfo Lib "User32.dll" Alias "GetMonitorInfoA" (ByVal
hMonitor As Integer, ByRef lpMI As MonitorInfoEx) As Integer
and the Structure that I have to hold each monitor's info is:

Private Structure MonitorInfoEx
Public cbSize As Integer
Public rcMonitor As RectAPI
Public rcWork As RectAPI
Public dwFlags As Integer
Public szDevice As String <<=== that has to be 32 characters long
End Structure

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Private Structure MonitorInfoEx
Public cbSize As Integer
Public rcMonitor As RectAPI
Public rcWork As RectAPI
Public dwFlags As Integer

<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)> _
Public szDevice As String
End Structure

Private Declare Auto Function GetMonitorInfo Lib "user32" _
(ByVal hMonitor As IntPtr, _
ByRef lpmi As MonitorInfoEx) As Boolean

....
Dim monitorInfo As MonitorInfoEx

If GetMonitorInfo(hMonitor, monitorInfo) Then
Console.WriteLine(monitorInfo.szDevice)
Else
Dim ex As Win32Exception(Marshal.GetLastWin32Error())
Console.WriteLine(ex.Message)
End If

HTH
 
Thanks Tom, this seems it may just do the trick at setting the length of the String. The next problem I encountered though is that for GetMonitorInfo to work, you apparently *must* set the .cbsize value of the MONITORINFOEX Struct to be the struct type's actual size. Without doing this, the GetMonitorInfo function does actually succeed yet it doesn't fill any of the struct's components up with any data. Setting the .cbsize value can be done with the C++ method "sizeof(MONITORINFOEX)", this will return the size of the actual whole struct type. Unfortunately, VB .net doesn't support sizeof and apparently has no equivalent either (C# has it though)

Would you know of a get-around for this too? Perhaps I could call the sizeof function out of the appropriate C++ .dll from within VB.net and use its return value? I just need to know the dll that holds it and it's alias now

Thanks again
Ia
Public szDevice As String <<=== that has to be 32 characters lon

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
Private Structure MonitorInfoE
Public cbSize As Intege
Public rcMonitor As RectAP
Public rcWork As RectAP
Public dwFlags As Intege

<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)>
Public szDevice As Strin
End Structur
 
Thanks Tom, this seems it may just do the trick at setting the length of the String. The next problem I encountered though is that for GetMonitorInfo to work, you apparently *must* set the .cbsize value of the MONITORINFOEX Struct to be the struct type's actual size. Without doing this, the GetMonitorInfo function does actually succeed yet it doesn't fill any of the struct's components up with any data. Setting the .cbsize value can be done with the C++ method "sizeof(MONITORINFOEX)", this will return the size of the actual whole struct type. Unfortunately, VB .net doesn't support sizeof and apparently has no equivalent either (C# has it though).

Would you know of a get-around for this too? Perhaps I could call the sizeof function out of the appropriate C++ .dll from within VB.net and use its return value? I just need to know the dll that holds it and it's alias now!

monitorInfo.cbSize = Marshal.SizeOf(monitorInfo)

Should fix you up.
 
Back
Top