VB.NET how to pass a struct? anyone? - Windows Mobile Development and Hacking General

Anyone know how to pass a pointer to a struct in VB.NET that could help me out?
" pGPSPosition
Pointer to a GPS_POSITION structure. On return, this structure is filled with location data obtained by the GPS Intermediate Driver. The dwValidFields member of the GPS_POSITION instance specifies which fields of the instance are valid."
This is from a link on MS site: (http://msdn2.microsoft.com/en-us/library/bb202050.aspx)
So how do I do this in VB?
Looking for a little love here...
TIA,

WM6 SDK contains the sample with the complete wrapper around the GPS intermediate driver in the managed code
But one warning - on some devices (namely HTC Artemis) the serious bug in some version of code provided by Microsoft to Oem return an error when calling functions this API. Communication with a GPS via serial port is still more reliable for a commercial solutions...

Appreciate the response but do you have any source that I can use with VB? My biggest problem is actually retrieving any information from the GPS device using the "GPSGetPosition" function. (see other link - http://forum.xda-developers.com/showthread.php?p=1979418#post1979418)
"But one warning - on some devices (namely HTC Artemis) the serious bug in some version of code provided by Microsoft to Oem return an error when calling functions this API"
Could you be a little more specific?
TW,

Semi manual marshhalling of structure to pointer:
Dim pointerM As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(myStruct))
Marshal.StructureToPtr(myStruct, pointerM, False)
Marshal.FreeHGlobal(pnt)
Ad Artemis and another devices) GPS structure has invalid size from old platform builder and intermediate driver (GPS API) refuse it with error.

RStein,
As I was reading about it appeared that Marshaling was going to have to be used in some way since I'm pretty sure that the struct would need to be passed to the C function.
Which brings me to another Q since it appears your are savy at programing in C - how to convert the following C struct?
The struct appears to have a couple of arrays and a few other enums thats are passed to the function, how is that handled in VB?
DWORD GPSGetPosition(
HANDLE hGPSDevice,
GPS_POSITION *pGPSPosition,
DWORD dwMaximumAge,
DWORD dwFlags
);
typedef struct _GPS_POSITION {
DWORD dwVersion;
DWORD dwSize;
DWORD dwValidFields;
DWORD dwFlags;
SYSTEMTIME stUTCTime;
double dblLatitude;
double dblLongitude;
float flSpeed;
float flHeading;
double dblMagneticVariation;
float flAltitudeWRTSeaLevel;
float flAltitudeWRTEllipsoid;
GPS_FIX_QUALITY FixQuality;
GPS_FIX_TYPE FixType;
GPS_FIX_SELECTION SelectionType;
float flPositionDilutionOfPrecision;
float flHorizontalDilutionOfPrecision;
float flVerticalDilutionOfPrecision;
DWORD dwSatelliteCount;
DWORD rgdwSatellitesUsedPRNs[GPS_MAX_SATELLITES];
DWORD dwSatellitesInView;
DWORD rgdwSatellitesInViewPRNs[GPS_MAX_SATELLITES];
DWORD rgdwSatellitesInViewElevation[GPS_MAX_SATELLITES];
DWORD rgdwSatellitesInViewAzimuth[GPS_MAX_SATELLITES];
DWORD rgdwSatellitesInViewSignalToNoiseRatio[GPS_MAX_SATELLITES];
} GPS_POSITION, *PGPS_POSITION;
Click to expand...
Click to collapse
I had a suggestion to create a library from the C# SDK, how difficult would that be? Would it be easier than trying to convert to VB?
Can you help with that?
Thanks for any feedback...

Related

GPRS connectivity in EVB

I have an EVB application that connects to GPRS using a library from Sapphire Solutions.
This has worked reasonably well, but doesn't give me a lot of control of what is going on.
What other methods have people tried? Any hints?
here
I also was lookinf for this solution forever and never found it so i wrote the software myself. Here is the dll that you need to connect to the internet through evb it connects to the default connection no problems.
http://xdaconnect.wastedbrains.com
have fun,
Dan Mayer
Thanks for this. I'll have a play.
The stupid thing is, O2 have told me that I should be using their routines. But nobody can tell me what the routines are, how to find them or give me any information about them whatsoever!
Compare and contrast with Vodafone who actually know a thing or two about implementing mobile systems, but don't have a product to implement...
Code:
Public Declare Function AllocPointer Lib "VBPointers" Alias "VB_AllocPointer" (ByVal nSrcSizeInBytes As Long) As Long
Public Declare Function AllocStringPointer Lib "VBPointers" Alias "VB_AllocStringPointer" (ByVal str As String) As Long
Public Declare Function FreePointer Lib "VBPointers" Alias "VB_FreePointer" (ByVal Pointer As Long) As Long
Public Declare Sub SetLongAt Lib "VBPointers" Alias "VB_SetLongAt" (ByVal Pointer As Long, ByVal OffsetInBytes As Long, ByVal Value As Long)
Public Declare Function PhoneMakeCall Lib "Phone" (ByVal CallInfo As Long) As Long
Public Sub Dial(Number_to_dial As String)
CallInfo = AllocPointer(24) ' sizeof (PHONEMAKECALLINFO)
Call SetLongAt(CallInfo, 0, 24) ' cbSize
Call SetLongAt(CallInfo, 4, 1) ' dwFlags = PMCF_DEFAULT
PhoneNumber = AllocStringPointer(Number_to_dial)
Call SetLongAt(CallInfo, 8, PhoneNumber) ' pszDestAddress
PhoneMakeCall (CallInfo)
FreePointer (PhoneNumber)
FreePointer (CallInfo)
End Sub
The xdaconnect dll posted by Dan is pretty good at getting a connection. The problem is that it has to be registered on each device using eVC. My problem is that I want to make a cd so that other people who dont have eVC can install the device. Normally I would do this with dllRegisterServer or by including the file in the manifest file of dll's to be registered when a program is installed. The problem is that this dll wont register alone, an error is returned back that "dllRegsisterServer is not included in the dll".
Can anyone help?
The dll and eVC project file is available for download at http://xdaconnect.wastedbrains.com
Many thanks
Tony

lineGetID returns a NULL handle

Hi everybody
I tried to achieve a handle for readFile/writeFile operations using lineGetID.
The call to the function passed without errors. My problem is that the handle that I get is 0..., and I should make IO operations some how...
My code:
lRet := lineGetID( FLineHandle, 0, 0, LINECALLSELECT_LINE, PVarString, szClassType );
if lRet = 0 then
begin
FDevHandle := (LPHANDLE(PByte(PVarString) + PVarString^.dwStringOffset ))^;
// some more non relevant code which checks the validity of FDevHandle....
end;
The call to lineGetID is done after successful call to lineGetOpen. I test my application on i-mate jam with WM2003.
Thanks ahead
Kobi
I solved the problem
Hi everybody
For those who encounters the same problem as mine here is the solution that I finally found:
1. The Handle is NULL if we call the lineGetID using LINECALLSELECT_LINE. We should call lineGetID after getting into the LINECALLSTATE_CONNECTED state and use the LINECALLSTATE_CALL parameter. This information was found in the MSDN.
2. The lineGetID (as well as other line functions) doesn't report (I use TAPI 2.0 with WM-2003 on i-mate jam - the cellular line channel) the error LINEERR_STRUCTURETOOSMALL, so immediately after calling the lineGetID I added the following line (I use free pascal compiler):
if (Result = 0) and (PVarString^.dwTotalSize < PVarString^.dwNeededSize) then
Result := integer(LINEERR_STRUCTURETOOSMALL);
After this line comes the characteristic TAPI code which checks if either we should reallocate the previous block, or we can already use the data that call should have given to us.
Just after considering these 2 issues I got a vaild Handle...
Kobi
Hi Kobi,
I also having difficulties creating handle to write data on this TAPI Line, Can you please help me translate your code in VB.NET or C#, I am using VB and C# on developing application in WM2003.
Many thanks in Advance,
Eefendi
More complete code
Hi Eefendi
I neither know VB.NET nor C#, so it will be in Pascal, but I will add comments.
The code itself should be activated after you received the LINE_CALLSTATECONNECTED message/event (depends on the mechanism you selected when you called lineInitialize).
The CallHandle is a variable holds the handle of the call you want to achieve a handle to its stream (you achieve CallHandle, in incoming call for example, using LINE_CALLSTATEOFFERING message/event). The final result we want is stored in Handle. The line itself should be opened using "comm" or "comm/datamodem" class type.
var
VarSize,
Res : integer;
PVarString : LPVARSTRING;
szClassType : PWideChar = 'comm/datamodem';
// these variables definitions is equivalent to the following C code:
// int VarSize, Res;
// LPVARSTRING PVarString;
// TCHAR *szClassType = "comm/datamodem";
begin
VarSize := sizeof(VARSTRING);
Handle := 0;
repeat
GetMem( PVarString, VarSize ); // alloc VarSize bytes
PVarString^.TotalSize := VarSize;
Res := lineGetID( 0, 0, CallHandle, LINECALLSELECT_CALL, PVarString, szClassType );
if (Res = 0) and (PVarString^.TotalSize < PVarString^.NeededSize) then
Res := LINEERR_STRUCTURETOOSMALL;
if Res = LINEERR_STRUCTURETOOSMALL then
VarSize := PVarString^.NeededSize
else
if Res = 0 then // no error
Handle := LPHANDLE(PByte(PVarString) + PVarString^.dwStringOffset)^;
FreeMem( PVarString, PVarString^.TotalSize ); // free memory
until Res <> LINEERR_STRUCTURETOOSMALL; // finish the repeat until loop if this condition is TRUE
if (Handle <> 0) and (Handle <> INVALID_HANDLE_VALUE) then
//;use it as you wish....
end;
Some help to you for conversion:
1. PVarString^.TotalSize using C means PVarString->TotalSize
2. PByte using C means char*
3. type cast for example to PByte is done by PByte(...) while using C it is done by (PByte)...
4. Refering to a value which is referenced by the pointer P and storing it in variable X is done by "X := P^;". using C it is done by "X = *P;".
5. The operator <> means not equal. in C it is !=.
I hope it will be easy to you to translate it to C or any other language you want.
Good luck with your project.
Kobi
TAPI does seem to pop up a lot.
Have you looked at my code I posted a while back here ?
http://forum.xda-developers.com/viewtopic.php?t=18978
Hi Vangelderp and Kobi,
thanks for spending your time answering my questions and also thanks for the code provided. I use VB.Net 2003 on programming my pocket PC 2003, you guys provide me the code using pointer data type which is not supported in VB.net, so I am having trouble converting it. ( When I was learning C++, pointer is always make me confuse :roll: ). I wish you guys will be kind enough helping me convert it to VB.Net, just for small part to get Handle. :wink:
Mant Thanks in advance,
Eefendi

data type conversion in eVC++

Hello Everyone
I hope this is not too trivial a question. I am new to eVC. I would like to know how to convert from data type LONG to data type CHAR OR STRING in eVC.
Long myLong=1134.67
In VB the conversion will simply be
myString=STR(myLong)
How can I achieve this in eVC++?
Also someone please recommend some good books on eVC++.
Thanks.
ajanaman
evc++ is just like vc++
which is just like c++ with mfc on top of it
to do simple type casts you do
x=(Type)y;
here are some links also included dynamic type casts
http://www.cplusplus.com/doc/tutorial/typecasting.html
http://www.torjo.com/win32gui/doc/window_casting.html
Hello gsmtexts!
First I would like to point out that in C++ LONG data type is a 4 byte signed integer (in your example you use a floating point value).
Second I assume that by converting you mean representing the number as a string of characters an not just letting the computer assume that the variable contains ASCII values instead of a number.
Here's how you do it:
C++ language doesn't have string data type instead you use an array of char.
Example:
Code:
char myStr[255]; //you have a string of up to 255 ASCII chars.
double myVal = 50.1234; //a double precision floating point value
_gcvt(myVal, 6, myStr); //convert the string
You could use one of the functions (you can search the MSDN site for more details): _gcvt, _ecvt, _fcvt, but there is a simpler way as well:
Code:
WCHAR myStr[255]; //win CE works with Unicode strings.
float myVal = 1.2345; //the value
swprintf(myStr, L"The value: %f", myVal); //creates a string: 'The value: 1.2345'
Finally if you are using MFC:
Code:
CString str;
float myVal = 1.2345;
str.Format(_T("The value: %f"), myVal);
As for books I can only recommend "Teach yourself C++", by Jesse Liberty, it got me started in C++ programming.
Good luck.
Dear levenum
many thanks - I have sratched my head for nearly a week and you gave me the solution just like that. _gcvt did it. u are a wonderful guru.
ajanaman
You are welcome gsmtexts!
But I am far from being a guru. I just like programming so I picked up a book or two and the ball started rolling. 8)
Anyway, since you chose to use _gcvt you should know that in order to use the string you get with windows API's like SetWindowText you will have to convert it to Unicode:
Code:
WCHAR uniBuffer[50]; //Unicode buffer
char myString[50]; //ASCII buffer
_gcvt(1.2345, 5, myString); //convert value to string
mbstowcs(uniBuffer, myString, 50); //convert ASCII string to Unicode
The standard c++ way would be:
double d=122.332;
std:stringstream oss;
oss << d;
std::string mystring=oss.str();
The standard c++ way would be:
double d=122.332;
std:stringstream oss;
oss << d;
std::string mystring=oss.str();

Learning how to program for Windows Mobile?

I've done some searching, and I know Windows CE uses Win32, which I know to an extent. I was curious if there are any good free resources for learning WinCE-Win32, or if I should simply use my existing books for MFC/Win32. Microsoft's site kinda sketchy, and MSDN not being very useful. I did get Microsoft Embedded Visual C++ working and compiled a test app which worked on my MDA and on the emulator.
i would just start coding
miniMFC and compact .net framework is soo close it's only
some controls and options you dont have
ortherwise it's the same thing
learning by doing and having ones fingers down and dirty
into the code is where you learn the most
Yep, that's just how I learned when I switched to coding for PPCs.
Any way here are a few major differences to start you off:
1) All API's that use strings are in UNICODE. ASCII versions were removed.
2) For most API's that have an 'ext' version the regular version was removed. Example: ExtTextOut - yes, TextOut - no.
3) When dealing with files, all paths must be absolute. No '..\file.x' and 'file.x' will give you the file in device root and not the app directory.
And here is a nice site for pocket PC specific apps:
www.pocketpcdn.com
Has articles on just about everything from making dialogs not full screen to writing today plug-ins.
levenum said:
Yep, that's just how I learned when I switched to coding for PPCs.
Any way here are a few major differences to start you off:
1) All API's that use strings are in UNICODE. ASCII versions were removed.
2) For most API's that have an 'ext' version the regular version was removed. Example: ExtTextOut - yes, TextOut - no.
3) When dealing with files, all paths must be absolute. No '..\file.x' and 'file.x' will give you the file in device root and not the app directory.
And here is a nice site for pocket PC specific apps:
www.pocketpcdn.com
Has articles on just about everything from making dialogs not full screen to writing today plug-ins.
Click to expand...
Click to collapse
I knew about how everything was Unicode. Is there an easy way to create unicode strings? I remember there was something in MFC macro like TEXT() that did something like that, but the specifics are missing. I remember there was a knowledge base article on this, but I can't find it.
Also, what's the difference between the Ext version and the non-ext versions of an app?
EDIT: Unless I'm mistaken, I just need to put my strings in _T("*string*")
Yes, you're right, this is how you write strings in your code:
Code:
WCHAR uniStr[] = L"Unicode string";
or if you are using MFC:
Code:
CString uniStr = _T("Unicode string");
and if you have a ASCII string you want converted to UNICODE
use mbstowcs function. (CString class has a built in conversion)
As for the 'ext' API's they just give you more parameters to better control the result of whatever they are doing. In desktop windows if you didn't want to call a function with 10 parameters you usually had a simpler version of it where some things were default.
Example:
Code:
BOOL TextOut(
HDC hdc, // handle to DC
int nXStart, // x-coordinate of starting position
int nYStart, // y-coordinate of starting position
LPCTSTR lpString, // character string
int cbString // number of characters
); //5 parameters
BOOL ExtTextOut(
HDC hdc, // handle to DC
int X, // x-coordinate of reference point
int Y, // y-coordinate of reference point
UINT fuOptions, // text-output options
CONST RECT *lprc, // optional dimensions
LPCTSTR lpString, // string
UINT cbCount, // number of characters in string
CONST INT *lpDx // array of spacing values
); // 8 parameters
what would be your suggestion for a newbie to learn programming for PPC?
I'm beggining to have interest in doing this but have absolutely no idea where to start.
thanks for any advise.
For complete newbies, I wrote this post a while back:
http://forum.xda-developers.com/viewtopic.php?p=209136#209136
V

accelerometer(lg gm750) method signatures

attached the.dll of the lg gm750 in case they serve of something
USER iamspv
First take a look at the Unified Sensor Api at codeplex.
My solution is based on the Samsung sensor class, modified to meet the peculiarities of the LG GM750.
First of all, the import of the DeviceIoControl in NativeMethods.cs must be modified such way dwIoControlCode is type uint, and the buffers are byte:
Code:
[DllImport("coredll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool DeviceIoControl(IntPtr hDevice, uint dwIoControlCode, [In] byte[] inBuffer, int nInBufferSize, [Out] byte[] outBuffer, int nOutBufferSize, ref int pBytesReturned, IntPtr lpOverlapped);
After a long time dissassembling the accelsensor.dll and and a lot of trial and error testing I came to this conclusion that works:
The constant that starts/stops data output becomes:
Code:
const uint ACCOnRot = 0x1014EE8;
const uint ACCOffRot = 0x1014EE8;
and for reading values:
Code:
const uint ACCReadValues = 0x1014F10;
The difference between start and stop comes from the input given in DeviceIoControl method as follows:
Code:
Code:
public static LGAccSensor Create()
{
DeviceIoControl(ACCOnRot, new byte[1] {1}, new byte[4] );
return new LGAccSensor();
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
DeviceIoControl(ACCOffRot, new byte[1] {0}, new byte[1] );
}
The DeviceIoControl inside the accelerometer class becomes
Code:
Code:
public static void DeviceIoControl(uint controlCode, byte[] inBuffer, byte[] outBuffer)
{
IntPtr file = NativeMethods.CreateFile("ACC1:", 0, 0, IntPtr.Zero, ECreationDisposition.OpenExisting, 0, IntPtr.Zero);
if (file == (IntPtr)(-1))
throw new InvalidOperationException("Unable to Create File");
try
{
int bytesReturned = 0;
int inSize = sizeof(byte) * inBuffer.Length;
int outSize = sizeof(byte) * outBuffer.Length;
if (!NativeMethods.DeviceIoControl(file, controlCode, inBuffer, inSize, outBuffer, outSize, ref bytesReturned, IntPtr.Zero))
throw new InvalidOperationException("Unable to perform operation.");
}
finally
{
NativeMethods.CloseHandle(file);
}
}
Note that the accelerometer device is called ACC1:.
Further the method that returns the three component vector becomes
Code:
Code:
public override GVector GetGVector()
{
byte[] outBuffer = new byte[4];
DeviceIoControl(ACCReadValues, new byte[1] {1}, outBuffer);
GVector ret = new GVector();
int accx = outBuffer[2];
if (accx <=31)
ret.X = accx/2.17;
else
ret.X = (accx-64)*0.47;
ret.X = -ret.X;
int accy = outBuffer[1] ;
if (accy <=31)
ret.Y = accy/2.17;
else
ret.Y = (accy - 64) * 0.47;
int accz = outBuffer[0] ;
if (accz <=31)
ret.Z = accz/2.17;
else
ret.Z = (accz - 64) * 0.47;
double somefactor = 1; return ret.Scale(somefactor);
}
Note that the when called with AccReadValues parameter, the DeviceIoControl returns three bytes each of them containing a signed 6 bit 2's complement value.Basicly there are values on 6 bit ranging from -32 to +31. In the docs below there are tables that put in correspondence these values with acceleration in range -1.5g +1.5g which are the limits of the device. The code I wrote returns acceleration in meters/second2 where 1g=9.8 m/s2. That information I extracted from the technical specifications of the MMA7660FC accelerometer, as found at(try a google search). Also, the type of the accelerometer circuit is found in the service manual (I only found the service manual for LG GM730 which is pretty close).The same thing I also posted at codeplex.
Reply With Quote
It already works! There is nothing more to do about it than use the code in your applications (I speak as a programmer and for programmers). I only showed everyone interested in developing for LG GM750 the steps to modify the SamsungGSensor class from "Unified Sensor Api" at codeplex to work with a LG. Just get the rest of the code from there and put it toghether.
Now there are two directions:
Direction #1
If you want to develop applications that aim to be portable between HTC, Samsung, LG, Toshiba, etc, and you want to use Unified Sensor Api then..
the person responsible for the unified api project at codeplex should make the update to the library as soon as possible such way the library should keep compatibility with the adressed devices. I'm just contributing with some results. That's because the initial code was not very general (ie. the initial parameter types to deviceiocontrol invoked from coredll didn't work with this solution) I had to make some modifications to the code that work with the LG but affect other devices' sensor classes. Now, if the update doesn't come up soon, no problem, anyone just gets the code from codeplex, adds a new class for LG, copies code from Samsung, renames Samsung with LG, adds my modifications, corrects syntax errors, compiles, et voila . . the library is updated to support LG GM750.
Direction #2
If you develop only for LG, just write a LG class as presented above and don't care about other devices.
If you don't know how to use your new class, the project at codeplex has some examples and you'll easily see inside the code how to instantiate sensors, how to read data at certain moments using a timer, and how to capture screen rotation events.
And for your long awaited joy to see it working, I attached the sensor test program along with a version of sensors.dll compiled by me, that works for GM750.
Now get your fingers toghether on the keyboard and start developing for LG
now should work in an emulator as that one of htc in omnia splitting of what we arrange
great work!
thanks much!
htcemu v0.91 /sensors.dll Problems
Hello all,
when I last November asked for a htcemu for LG750, I have not expected that there will be a emu dll so soon.
Thanks to iamspv and others, we now can use g-sensor apps as normal.
Nearly - some apps does not work or crash.
So my favorite alarm clock, klaxon crashes when alarm is activated. Waterlevel also does not work. It looks that both apps use the managed code dll sensors.dll. Even if I exchange the original dll with the one posted here from beginning of february, it does not work. Does anybody has a solution for this ?
For using landscape mode in app I now got best results with changescreen which works almost perfect. It is also possible to exclude some programs like some LG apps which do not support landscape mode.
how did you make other apps work? on my layla only test works and nothing else
creative232 said:
attached the.dll of the lg gm750 in case they serve of something
Click to expand...
Click to collapse
Did you create a running VS 2008 solution for this?. I'm interested.
Will this work on other LG's?

Categories

Resources