Click here to Skip to main content
6,630,586 members and growing! (15,320 online)
Email Password   helpLost your password?
Languages » C# » Applications     Intermediate

WeatherNotify

By rantanplanisback

Show weather in status bar and/or in a window. Details can be shown on another window. This is a multiple languages/units software (to add more languages, just put an XML file in the language directory). This is a C# translation of phpweather.
C#, Windows, .NET 1.1VS.NET2003, Dev
Posted:20 Jan 2005
Updated:16 May 2005
Views:72,297
Bookmarked:93 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
28 votes for this article.
Popularity: 5.38 Rating: 3.72 out of 5
2 votes, 7.1%
1
3 votes, 10.7%
2
2 votes, 7.1%
3
6 votes, 21.4%
4
15 votes, 53.6%
5

Sample Image - WeatherNotify.jpg

Introduction

This shows the weather in the status bar and/or in a window.

Details can be shown on another window. This is a multiple languages/units software (to add more languages, just put an XML file in the language directory). This is a C# translation of phpweather.

This shows a good example for XML serialization, the use of notifyicons, dynamic image loading, multiple language interface and regular expressions.

First we download information from weather.noaa.gov. Next we parse this information using regular expressions to retrieve full weather information: clouds, temperature, pressure, wind information, precipitation, visibility. This helps us to associate the correct image to the corresponding weather.

Content

This application just connects to weather.noaa.gov every hour to retrieve weather information. All the information is in a string like "TFFR 281000Z 00000KT 9999 FEW020 19/18 Q1011 NOSIG" called METAR. (Information on METAR decoding can be found here.)

So we just parse this string using regular expressions to find weather information (temperature, wind, pressure ...). After we retrieve all the required information, we just show the image associated with the weather conditions and make a report containing all this information.

Project contents:

  • class METAR used for the parsing: only a big parsing of regular expressions.
  • ereg: use of Microsoft regular expression functions to work like the PHP one's.
  • class used to store decoded weather information: clouds, humidity, precipitation, runway, temp, visibility, weather, wind.
  • class to easily convert values: wind, pressure, temperature, length, height, wind speed.
  • xml_access: used for XML serialization for options and languages. It is used to save/restore object values in/from XML files.
  • tcp_socket: class to retrieve data on the Internet (part of the network stuff project available on this website).
  • class METAR download: launch download every hour or retry download 5 min after a failure.
  • forms for user interface.
  • other utility class (file_access, XP style).

Most important points:

The PHP ereg function emulation

We just try to make a similar function as that of PHP to avoid changing the parsing too much.

public class ClassEreg
{
    // check if input_string match pattern and return groups in strregs

    public static bool ereg(string pattern,string input_string,
                           ref string[] strregs)    
    {
        if (input_string=="")
            return false;
        if (!System.Text.RegularExpressions.Regex.IsMatch(input_string,
           pattern,System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            return false;
        System.Text.RegularExpressions.Match m
              = System.Text.RegularExpressions.Regex.Match(input_string,
                     pattern, 
                     System.Text.RegularExpressions.RegexOptions.IgnoreCase);
        strregs=new string[m.Groups.Count];
        for (int cpt=0;cpt<M.GROUPS.COUNT;CPT++)  
        {
            if {m.Groups[cpt].Captures.Count >0)
                strregs[cpt]=m.Groups[cpt].Captures[0].Value;
            else
                strregs[cpt]="";
        }

        return true;
    }
    // just check if input_string match pattern

    public static bool ereg(string pattern,string input_string)
    {
        return System.Text.RegularExpressions.Regex.IsMatch(input_string,
                      pattern,
                      System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    }
}

These functions are called during all the parsing (the METAR class is only a long boring parsing). Here's a sample usage:

    string[] regs=null;
    string part="010V090";
    if (ClassEreg.ereg("^([0-9]{3})V([0-9]{3})$", part,ref regs))
    {
        /*
        * Variable wind-direction
        */
        this.wind.direction.var_beg = System.Convert.ToDouble(regs[1]);
        this.wind.direction.var_end = System.Convert.ToDouble(regs[2]);
    }

Dynamic image loading

We use a PictureBox and its property PictureBox.Image to show images in forms.

        private System.Windows.Forms.PictureBox picturebox_weather;
        public void set_img_weather(string fullpath)
        {
            Image img=get_image(fullpath);
            if (img!=null)
                this.picturebox_weather.Image=img;
        }
        private Image get_image(string fullpath)
        {
            try
            {
                return Image.FromFile(fullpath);
            }
            catch
            {
                MessageBox.Show( "File "+fullpath+" not found.","Error",
                                 MessageBoxButtons.OK,MessageBoxIcon.Error);
                return null;
            }
        }

Dynamic image loading for notify icon

            private System.Windows.Forms.NotifyIcon notify_icon;
            string img_path="image.png";
            // create a ComponentModel.Container if not exists

            if (this.components==null)
                this.components = new System.ComponentModel.Container();
            notify_icon=new System.Windows.Forms.NotifyIcon(this.components);
            // use the GetThumb function to resize image with good quality

            notify_icon.Icon=System.Drawing.Icon.FromHandle(
                       this.GetThumb(new Bitmap(img_path),16,16).GetHicon());

Text for notify icon

        private void drawstring_in_notify_icon(string text, 
                                               NotifyIcon notify_icon)
        {
            // Create a graphics instance that draws to a bitmap

            Bitmap bitmap = new Bitmap( 16, 16,
                         System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            Graphics graphics = Graphics.FromImage(bitmap);

            // FONT

            System.Drawing.Font drawFont
                       = new System.Drawing.Font("Arial Narrow",8,
                                            System.Drawing.FontStyle.Regular);

            // TEXT

            string drawString = text;

            SizeF drawStringSize = new SizeF();
            //Measure the Copyright string in this Font

            drawStringSize = graphics.MeasureString(drawString, drawFont);

            // BRUSH

            System.Drawing.SolidBrush drawBrush
                                    = new System.Drawing.SolidBrush(
                                         Color.FromArgb( 255, 255, 255, 255));
            // center text in icon image

            graphics.DrawString(drawString, drawFont, drawBrush, 
                   16/2-drawStringSize.Width/2,16/2-drawStringSize.Height/2);

            notify_icon.Icon=System.Drawing.Icon.FromHandle(bitmap.GetHicon());

            drawFont.Dispose();
            drawBrush.Dispose();
            graphics.Dispose();
        }

XML loading/saving

The trick is the same for options, language and language interface XML files. We just use XML serialization. The following sample is for the options class:

        public static ClassOptions load(string config_file_name)
        {
            try
            {
                return (ClassOptions)
                            XML_access.XMLDeserializeObject(config_file_name,
                                                       typeof(ClassOptions));
            }
            catch
            {
                return new ClassOptions();
            }
        }
        public bool save(string config_file_name)
        {
            try
            {
                XML_access.XMLSerializeObject(config_file_name,this,
                                              typeof(ClassOptions));
                return true;
            }
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show(e.Message,"Error",
                    System.Windows.Forms.MessageBoxButtons.OK,
                    System.Windows.Forms.MessageBoxIcon.Error);
                return false;
            }
        }

Where the XML serialization class is the following:

    using System;
    using System.IO;
    using System.Text;
    using System.Xml;
    using System.Xml.Serialization;

    public class XML_access
    {
        /// simple sample of call

        /// XMLSerializeObject("samplei.xml",i,typeof(OrderedItem));

        /// sample of call for ArrayList

        /// XMLSerializeObject("sampleal.xml",

        ///            (OrderedItem[])al.ToArray(typeof(OrderedItem)),

        ///            typeof(OrderedItem[]));


        public static void XMLSerializeObject(string filename,object obj,
                                              System.Type typeof_object)
        {
            Stream fs=null;
            try
            {
                XmlSerializer serializer = new XmlSerializer(typeof_object);
                // Create an XmlTextWriter using a FileStream.

                fs = new FileStream(filename, FileMode.Create,
                                    System.IO.FileAccess.ReadWrite );
                XmlWriter writer = new XmlTextWriter(fs,
                                    System.Text.Encoding.Unicode);
                // Serialize using the XmlTextWriter.

                serializer.Serialize(writer, obj);
                writer.Close();
                fs.Close();
            }
            catch(Exception e)
            {
                if (fs!=null)
                    fs.Close();
                System.Windows.Forms.MessageBox.Show( e.Message,
                                   "Error",
                                   System.Windows.Forms.MessageBoxButtons.OK,
                                   System.Windows.Forms.MessageBoxIcon.Error);
            }
        }
        /// simple sample of call

        /// OrderedItem i=(OrderedItem)XMLDeserializeObject("simple.xml",

        ///                           typeof(OrderedItem));

        /// sample of call for ArrayList

        /// System.Collections.ArrayList al=

        ///       new System.Collections.ArrayList((OrderedItem[])

        ///       XMLDeserializeObject("sampleal.xml",typeof(OrderedItem[])));

        public static object XMLDeserializeObject(string filename,
                                                  System.Type typeof_object)
        {
            // Create an instance of the XmlSerializer specifying type and 

            //namespace.

            XmlSerializer serializer = new XmlSerializer(typeof_object);
            // A FileStream is needed to read the XML document.

            FileStream fs = new FileStream(filename, FileMode.Open);
            XmlReader reader = new XmlTextReader(fs);
            // Declare an object variable of the type to be deserialized.

            object obj;
            // Use the Deserialize method to restore the object's state.

            obj = serializer.Deserialize(reader);
            reader.Close();
            fs.Close();
            return obj;
        }
    }

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

rantanplanisback


Member
Jacquelin POTIER
jacquelin.potier@free.fr
http://jacquelin.potier.free.fr/
Location: France France

Other popular C# articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 21 of 21 (Total in Forum: 21) (Refresh)FirstPrevNext
GeneralSorted country/city combobox Pinmembercoderider9:32 8 Feb '06  
GeneralRe: Sorted country/city combobox Pinmemberrantanplanisback10:44 10 Feb '06  
GeneralCool article, i like it thanks. Pinmembermrskyok5:35 17 Jul '05  
GeneralAdding new city PinmemberYusuf D M18:06 27 Feb '05  
GeneralRe: Adding new city Pinsussjacquelin potier2:05 28 Feb '05  
GeneralRe: Adding new city Pinmemberbxb4:12 19 May '05  
GeneralOpen Source Spirit PinmemberJens Scheidtmann21:56 25 Jan '05  
GeneralRe: Open Source Spirit PinmemberCorinna John22:39 25 Jan '05  
GeneralRe: Open Source Spirit Pinmemberrantanplanisback10:55 26 Jan '05  
GeneralRe: Open Source Spirit Pinmemberrantanplanisback11:55 27 Feb '05  
GeneralUnhandled Exception... PinsupporterDrew Stainton7:46 21 Jan '05  
GeneralRe: Unhandled Exception... Pinmemberrantanplanisback9:23 21 Jan '05  
GeneralRe: Unhandled Exception... PinsupporterDrew Stainton9:40 21 Jan '05  
GeneralRe: Unhandled Exception... Pinmemberrantanplanisback11:40 25 Jan '05  
GeneralRe: Unhandled Exception... PinsupporterDrew Stainton13:34 25 Jan '05  
GeneralPlease explain the code PinmemberCorinna John0:53 21 Jan '05  
GeneralRe: Please explain the code Pinmembertoxcct3:29 21 Jan '05  
GeneralRe: Please explain the code Pinmemberrantanplanisback9:34 21 Jan '05  
GeneralRe: Please explain the code PinsitebuilderUwe Keim9:39 21 Jan '05  
GeneralRe: Please explain the code Pinmemberdnh12:56 25 Jan '05  
GeneralRe: Please explain the code Pinmemberrantanplanisback11:02 26 Jan '05  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 16 May 2005
Editor: Smitha Vijayan
Copyright 2005 by rantanplanisback
Everything else Copyright © CodeProject, 1999-2009
Web20 | Advertise on the Code Project