| Recently I noticed my buddy
Robbe has one of these "streamer" apps running in a small web
browser window on one of his machines so he can track his crummy stocks
and how badly they are doing (hehe). I mentioned that I thought I could
put together some sort of tray icon app that would be even better.
I didn't think it would be a lot of work because:
1) I already had done some screen-scraping code that did a pretty good
job of getting realtime quotes from Yahoo finance.
2) I figured all I would need to do is drop a NotifyIcon control on a
form and do it that way.
As luck would have it, I was only partly right. The NotifyIcon control
in .Net is particularly limited. You can hook it up to a context menu,
and you can set its Text property, and a few event handlers, and that's
about it. Forget about displaying those neat Windows XP - style balloon
tip thingies.
I searched the .NET and went through three different implementations
of people's .NET balloon tip classes, and there was only one that did
what I wanted - to close the balloon tip automatically on
both Windows 2000 and Windows XP machines - after the specified timeout
period.
The one I chose to use, a really first - class all - managed - code implementation,
is this one:
http://www.codeproject.com/useritems/TaskbarNotifier.asp
I leave you with the link above if you want to explore further; all the
necessary code to use same is in the downloadable solution below.
The only other thing left for me to do was to implement an elegant way
to pop up a form the first time the app is run in order to allow the user
to enter a list of their favorite stock symbols to check. While I was
at it, I also added a small textbox where you can enter a number of minutes.
By adding a timer control to the form, we can then show timed balloon
tips every X minutes with the latest real - time quotes, courtesy of Yahoo.
And, I put in a context menu item that takes you to the Yahoo Finance
page of all your quotes from your list so that you can look at stock charts,
get news, and financials. One caveat - it is illegal to redisplay Yahoo
quotes on another site. In this case, where it is for personal use and
you are going to frequently end up going to the Yahoo site via the context
menu item and see all their ads and stuff anyway, I reasoned they probably
won't get upset.
Once the first set of quotes has been retrieved, the Text property of
the NotifyIcon is set with the results, so when you mouse over the icon,
it will look like so:
And when the Balloon Tip comes up, it looks like this:
(Man, I didn't know Yahoo was up to $21! Last time
I looked, it was like $9.... Damn!)
The key methods in the project are the GetTickers method,
the WriteTickers method, and the GetQuotes method:
private
string GetTickers()
{
string sTickers=String.Empty;
try
{
sTickers = Registry.LocalMachine.OpenSubKey("Software\\PAB\\QuoteMinder\\TickerList").GetValue("Symbols").ToString();
txtMin.Text= Registry.LocalMachine.OpenSubKey("Software\\PAB\\QuoteMinder\\AutoDisplay").GetValue("Min").ToString();
}
catch(Exception ex)
{
}
return sTickers;
}
private bool WriteTickers( string
strTickers, string strMin)
{
try
{
Registry.LocalMachine.CreateSubKey("Software\\PAB\\QuoteMinder\\TickerList").SetValue("Symbols",
strTickers);
stocks=strTickers;
Registry.LocalMachine.CreateSubKey("Software\\PAB\\QuoteMinder\\AutoDisplay").SetValue("Min",
strMin);
int intrval=Convert.ToInt32(strMin);
if(intrval==0)
{
this.timer1.Enabled=false;
}
else
{
this.timer1.Interval =Convert.ToInt32(strMin)*1000*60;
this.timer1.Enabled=true;
this.timer1.Start();
}
}
catch(Exception ex)
{
return false;
}
return true;
}
public string GetQuotes(string
QuoteList)
{
string serverURL= @"http://finance.yahoo.com/q?s=" +
QuoteList+"&d=e";
//Create a HttpWebRequest object for the server search URL
HttpWebRequest webreq = (HttpWebRequest)WebRequest.Create(serverURL);
webreq.MaximumAutomaticRedirections =60;
webreq.UserAgent="Mozilla/4.0 (compatible; MSIE 6.0;Windows
NT 5.0)";
//Retrieve HttpWebResponse object from the Search server URL
HttpWebResponse webresp = (HttpWebResponse)webreq.GetResponse();
//Create StreamReader object and pass the searchserver stream
as parameter, with ASCII encoding
StreamReader strm = new StreamReader(webresp.GetResponseStream(),
Encoding.ASCII);
//iterate through the stream, building return XML Document string
string res = strm.ReadToEnd();
strm.Close();
int startpos = res.IndexOf("Detailed");
string theQuotes="";
string tmpQuote="";
string[] arSymbols=QuoteList.Split(Convert.ToChar(" "));
for(int i = 0;i<arSymbols.Length;i++)
{
res=res.Substring(startpos);
startpos=res.IndexOf("<td nowrap align=left");
res=res.Substring(startpos);
startpos=res.IndexOf(">"+arSymbols[i].ToUpper()+"</a>");
res=res.Substring(startpos);
startpos = res.IndexOf("<b>" );
res=res.Substring(startpos);
int endpos = res.IndexOf("</b>");
tmpQuote=res.Substring(3,endpos-3);
theQuotes+= arSymbols[i] + " " +tmpQuote +" ";
startpos=endpos+3;
}
return theQuotes;
} // end GetQuotes
|
I also stuck in a P/Invoke call to do some toned beeps
with a wav file when the thingy comes up, just to add a little "flair".
You can download the whole solution and play with it to your heart's
content below. Some interesting "TO-DO's" might include changing
the way the WebRequest returns the stock results to perhaps a HashTable
or an ArrayList of structs, or even a DataTable, and thereby make a
provision in the Edit section to allow the user to add Limit Alerts
that will fire if any of their stocks go above or below preset defined
price limits (Oops! I got ambitious and already did it! - its all in
the download below!).
Download
the code that accompanies this article
| Peter Bromberg is a C# MVP, MCP, and .NET consultant who has worked in the banking and financial industry for 20 years. He has architected and developed web - based corporate distributed application solutions since 1995, and focuses exclusively on the .NET Platform. Pete's samples at GotDotNet.com have been downloaded over 41,000 times. You can read Peter's UnBlog Here. --><-- NOTE: Post QUESTIONS on FORUMS! |  |
Do you have a question or comment about this article? Have a programming problem you need to solve? Post it at eggheadcafe.com forums and receive immediate email notification of responses.
|