📜 ⬆️ ⬇️

Translation: 30 days Windows Mobile, the third day - GPS Compass (.NET vs WinAPI / C)

The third part of the translation cycle. Today we have on line the GPS Compass . Previous article, Bluetooth manager - http://habrahabr.ru/blogs/mobiledev/61703/ .

Chris Kraft. C #


The original is here .

I'm not a designer, but as mentioned earlier, the app should look attractive. Therefore, I found a very good free image for GPS compass in Wikimedia . When the basis for registration was chosen, it remains to determine the mechanism for obtaining GPS data. The following options were available:
  1. receive data via serial port
  2. using the OpenNetCF GPS library
  3. using GPS Intermediate Driver

')

GPS Compass application I stopped at the third option, because it is fairly new and, as the documentation says, “it’s useful because provides an intermediate level of abstraction between manufacturers of GPS devices and developers. " No one makes equipment in the same way - there are always features and pitfalls.


To test the application, I needed a device with GPS, and I even had this (AT & T Tilt), but unfortunately, the signal level in the room went to zero. Fortunately, Microsoft found the FakeGPS utility, which is just right for my purposes. This utility uses a text file with GPS data to emulate the functioning of a real GPS receiver.

In the documentation, I quickly discovered what I needed - a description of the structure of GPS_POSITION . For my simple application, I only needed one flHeading field, in degrees. North corresponds to zero.

At this stage, bundled with the Windows Mobile 6 SDK in the examples, I found the GPS Application - C: \ Program Files \ Windows Mobile 6 SDK \ Samples \ PocketPC \ CS \ GPS

Of course, it was possible to write everything from scratch, but I will repeat it again - always try to make the most of the available developments.

The application had a good status screen, which I called up on the menu. However, the main component of the application, of course, is displayed in the screenshot above. In principle, based on this example, you can build any application that uses GPS.

Download source code .

Note translator: Chris does not like to give code examples in his articles, preferring to immediately give a link to the file with the source code of the project. However, I allow myself to make particularly interesting inserts, if this is relevant. In the case of GPS Compass, it is useless to bring pieces of code, since it will be either too little or too much. I will say one thing - if Chris did not have an application from the SDK at hand, he would have suffered thoroughly, since in the example, all the wrappers are written around the native structures, enumerations and methods; this example is also good for studying the characteristics of marshalling large and complex structures.

Christopher Fairbairn. WinAPI - C


In Windows Mobile 5 and above, there is a unified API called GPS Intermediate Driver , which will allow multiple applications to simultaneously use one GPS device. This is a high-level interface that saves us from having to parse NEMA sentences , etc.

To connect to a GPS device, we need to connect gpsapi.h and call GPSOpenDevice
// GPS Intermediate Driver <br/>
HANDLE hGPS = GPSOpenDevice(NULL, NULL, NULL, 0);


* This source code was highlighted with Source Code Highlighter .


This API counts links , which means that every call to GPSOpenDevice must necessarily have a closing GPSCloseDevice. GPS equipment will disconnect only when the last client has terminated the connection.


Next, for information, we use the methods GPSGetPosition or GPSGetDeviceState to obtain the position or status of the device, respectively. For example, to get the current location, you can use the following code:

GPS_POSITION pos;<br> <br> // <br>memset(&pos, 0, sizeof (pos));<br>pos.dwVersion = GPS_VERSION_CURRENT;<br>pos.dwSize = sizeof (pos);<br> <br> // GPS intermediate driver <br> // . <br>GPSGetPosition(hGPS, &pos, 500000, 0); <br><br> * This source code was highlighted with Source Code Highlighter .


Please note that the GPS_POSITION structure contains the dwValidFlags field. This is a bitmask that tells you which fields contain the correct information. For example, if the GPS_VALID_LATITUDE flag is not set in the field, this means that the dblLatitude field cannot be relied on.

We use one interesting feature in our GPS compass. By passing two event handlers as parameters to the GPSOpenDevice method, we eliminate the need to periodically poll the device using GPSGetPosition. Instead, we simply wait until an event is triggered, with a guarantee of receiving data that is different from the previously obtained values.

Creating a menu.


This is the first application that required the menu. The menu is created in the resource editor and loaded using the SHCreateMenuBar . The call to this method is usually placed in the WM_INITDIALOG handler:

case WM_INITDIALOG:<br> // Configure the menu <br> SHMENUBARINFO mbi;<br> memset(&mbi, 0, sizeof (mbi));<br> mbi.cbSize = sizeof (mbi);<br> mbi.hWndParent = hWnd; // the dialog's handle <br> mbi.nToolBarId = IDR_MENU; // the menu resource id <br> mbi.hInstRes = GetModuleHandle(NULL);<br> mbi.dwFlags = SHCMBF_HMENU;<br> <br> // Create the menu <br> SHCreateMenuBar(&mbi);<br> break ; <br><br> * This source code was highlighted with Source Code Highlighter .


Next, there is a whole set of APIs for interacting with menu items. For example, you can activate or deactivate a specific item using the EnableMenuItem :
// Disable a menu item with id 'IDC_SOME_ITEM' <br>EnableMenuItem(hMenu, IDC_SOME_ITEM,<br> MF_BYCOMMAND | MF_GRAYED);<br> <br> // Enable a menu item with id 'IDC_SOME_ITEM' <br>EnableMenuItem(hMenu, IDC_SOME_ITEM,<br> MF_BYCOMMAND | MF_ENABLED); <br><br> * This source code was highlighted with Source Code Highlighter .


Note that the same method is called to set different states of menu items. The correct place for such calls is in the WM_INITMENUPOPUP handler. This message is sent to the menu owner immediately before the menu is displayed.

Download source code .

Conclusion from the translator


What I like in the translation of two articles at once - Chris describes how to quickly distribute the necessary functionality in C #, and Christopher always digs deeper and describes the subtleties of libraries that often can’t be seen from .net if you don’t understand. Accordingly, even if there is no need or desire to program in pure WinAPI, knowing how everything works inside is very useful.

Source: https://habr.com/ru/post/65185/


All Articles