theres a big problem when trying to talk to api or c applications/libraries using VisualBasic and that's the String, actually I've been doing a fair bit of research and there is a brilliant piece on it in the MSDN library that ships with VisualBasic 6.0 Professinal edition in the Books section under Hardcore Visualbasic.
VB nativley uses unicode where it can, Windows95 through NT accepts LPSTR type strings, NT prefers LPWSTR type strings (W for Widechar otherwise known as unicode).
VB3 used HLSTR which is a pointer, to a pointer with a length attribute then to the character stream which is your regular 8-bit byte-per-char string.
VB6 uses BSTR which is a null-terminated widechar string, inside the vb programming environment "this" has a length of 4 characters, in memory it's 10 characters (counting the wNull at the tail and not including it's length record).
The Byte datatype serves two purposes, one is a single unsigned byte for use as flags or values, can be used as a 'typeless' variable to store unformatted datablobs, the other purpose is to behave just like a C/C++/Java char datatype.
The dynamic byte array is compatible with the String datatype, i.e.
Dim bText() as byte
Dim MyString as String: MyString = "COWS!"
bText = MyString
bText will contain the word "COWS!"
debug.print bText
will reveal that fact, and even MsgBox although sometimes you need to convince it to let you do it, it's not a huge drama.
bText will also contain the UNICODE version of the string unlike various routines in VB that automatically convert to ASCII/ANSI strings which for some things are absolutley useless.
A fixed sized array (even one that can be redimmed) generally and 99.9% of the time will not allow you to directly assign the VB string to it.
This is my working solution to your code, if you test it with an 8 byte entry the first 8 bytes in the data array become occupied right up to the very top. PLEASE SAVE ANY CHANGES YOU MAKE BEFORE RUNNING THIS CODE, and feel free to try it in a secondary copy just in case it's not compatible at all, because if for any reason CpyMem violates memory space the VBIDE will exit with no warning!
Declare Sub CpyMem Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cLength As Long)
Type DATAQUERY
Data(0 To 55) As Byte 'feel free to replace my array notation with your constant
End Type
Function StringToDataQuery(QueryStr As String, QueryLength As Long) As DATAQUERY
Dim DQTemp As DATAQUERY 'because I'm bending the rules a little I do it this way
Dim bStrTemp() As Byte
bStrTemp = StrConv(QueryStr, vbFromUnicode) 'if you wish to preserve the unicode encoding
'this will causee the code to change a bit, but my understandign is that you want to trim
'the unicode encoding completley, there are two ways to go from here, one is a loop which
'assigns each byte value to the dataquery byte array, or there'st the more direct method
CpyMem DQTemp.Data(0), bStrTemp(0), QueryLength
'----Disregard if you already have experience with CopyMemory----
'I will now explain something very important, CpyMem or CopyMemory has no type checking
'it hammers memory from one source to another to whatever size you specify
'it is up to you to do bounds checking, i.e. that QueryLength MUST NOT be greater than
'the .Data field, because if it is you overwrite someone elses memory and it can either
'result in your program exiting with no warning, or crashing several programs even causing
'a system crash. CpyMem uses the datatype ANY which is a special case for API calls
'ANY passes a pointer to respective library, it works fine for everything EXCEPT
'visualbasic strings so don't even bother trying it, there is a work around if you do need to
'but it's too early in the morning for me to write it up.
StringToDataQuery = DQTemp
End Function
CpyMem or CopyMemory plays with pointers in vb, what I've given you is pretty straight forward and can be used with everything short of the actual VB string itself (which I won't explain why at this moment)
Yes VisualBasic has pointers, No it's not very popular, Purists would have my head for even mentioning them as they can be VERY DANGEROUS if you haven't throught out carefully about how it's going to interact with something especially when there are no bounds checking or anything else.
What you do with pointers and CpyMem is entirley up to you but be aware VB will not protect you, will not enforce Type checks AT ALL when using this arrangement.
It should be noted that RtlMoveMemory is an elegant fast solution to a loop with many iterations something that at this stage VB doesn't have a real match for. AND please be aware that "RtlMoveMemory" in the Decleration at the top of the code is CaSe-SeNsITiVe!
Another point to note is that you cannot just:
CopyMemory DQtemp.Data, bStrTemp, QueryLength
why? because you're passing the API a pointer to a pointer, not a Pointer to useable memory. (don't ask, just trust me on this one), if you want to hammer data using CopyMemory/CpyMem ALWAYS make sure that the first item in the array you want to manipulate is passed.
You can even CpyMemory DQTemp.Data(4), bStrTemp(4), 4
If this has been helpful let me know, if not, disregard. But I've had some suprising success working in VB using the api.