One of the new RegionInfo properties in the .NET Framework 2.0 is GeoId. The geographical ID is an integer that identifies a geographical region. As it uniquely identifies a geographical region, it can be used as a primary key in a database (Microsoft uses GeoIds to support products such as MapPoint). The numbers themselves are defined by Microsoft and can be referenced in the Table Of Geographical Locations (http://msdn.microsoft.com/library/default.asp?url=/library/enus/intl/nls_locations.asp). Apart from the GeoId's value as a unique identifier, it can be used to retrieve information about a geographical region (as opposed to a locale). Unfortunately, the .NET Framework does not have a GeoInfo class to store or retrieve this information, but we can write one. Geographical information is retrieved using the GetGeoInfo Win32 function: [DllImport("kernel32")] protected static extern int GetGeoInfo( int GeoId, SYSGEOTYPE GeoType, StringBuilder lpGeoData, int cchData, int language ); The GeoId comes straight from the RegionInfo.GeoId (if you are using the .NET Framework 1.1, you could use the information in the "Table Of Geographical Locations" to build a static lookup of GeoIds from their names). The GeoType identifies the type of information you are getting and is a SYSGEOTYPE. lpGeoData is a buffer into which the returned information is placed. cchData is the size of the buffer. language is the language identifier that you want the information to be returned in (1033 is English (United States)). SYSGEOTYPE is an enumeration: public enum SYSGEOTYPE { GEO_NATION = 0x0001, GEO_LATITUDE = 0x0002, GEO_LONGITUDE = 0x0003, GEO_ISO2 = 0x0004, GEO_ISO3 = 0x0005, GEO_RFC1766 = 0x0006, GEO_LCID = 0x0007, GEO_FRIENDLYNAME = 0x0008, GEO_OFFICIALNAME = 0x0009, GEO_TIMEZONES = 0x000A, GEO_OFFICIALLANGUAGES = 0x000B, }; To retrieve information using GetGeoInfo, you should call it once to get the buffer size and then a second time to retrieve the information itself. The following method is a convenient wrapper around the GetGeoInfo method: protected virtual string GetGeoInfoString(SYSGEOTYPE sysGeoType) { // find out the length of the geo information int length = GetGeoInfo(geoId, sysGeoType, null, 0, language); if (length == 0) return null; else { StringBuilder lpGeoData = new StringBuilder(length); // get the geo information int result = GetGeoInfo( geoId, sysGeoType, lpGeoData, length, language); if (result == 0) return null; else return lpGeoData.ToString(); } } The full GetInfo class is part of the source code for this book, but here is a cut-down version showing just the OfficialName property: class GeoInfo { private int geoId; private int language = 1033; public GeoInfo(int geoId) { this.geoId = geoId; } public GeoInfo(int geoId, int language) { this.geoId = geoId; this.language = language; } public string OfficialName { get { string geoInfo = GetGeoInfoString(SYSGEOTYPE.GEO_OFFICIALNAME); if (geoInfo != null) return geoInfo; else throw new GeoInfoException( "Failed to retrieve Geo Information", SYSGEOTYPE.GEO_OFFICIALNAME, geoInfo); } } } You use the GeoInfo class like this: RegionInfo regionInfo = new RegionInfo("en-US"); GeoInfo geoInfo = new GeoInfo(regionInfo.GeoId); MessageBox.Show("Official Name: " + geoInfo.OfficialName);
|