Click here to Skip to main content
Click here to Skip to main content

A modal dialog that fades the background to gray-scale imitating the XP shutdown screen

By , 23 Feb 2006
 

Introduction

DimmerDialog is a .NET class that shows a modal dialog which grays out the rest of the background, just like the Windows XP Shutdown dialog. This can be used when your application needs to show a very important message box or form that requires immediate user attention. The class allows you to show either a message box (where you can set the text, title and icon), or a Form instance.

How the class works

The XP Shutdown dialog shows a modal form, while the background fades to gray-scale. I've tried to simulate this, though my fading is not as smooth or impressive (I've used regular GDI stuff whereas the XP Shutdown dialog may have used more powerful techniques like DirectX). I create a new desktop (named with a GUID), switch to this desktop, show the background, fade it using a timer, and all this while the modal form or message box is kept on top. Here's an animated gif that shows the fading effect (quality is poor due to GIF color depth limitations).

Using the class

Here's some sample code that shows how you can show a message-box.

private void button2_Click(object sender, EventArgs e)
{
    DimmerDialog dimmer = new DimmerDialog();
    dimmer.ShowMessageBox(
        "You can show either a Form or a MessageBox here.", 
        "Fatal Error has occurred", MessageBoxIcon.Stop);
}

And here's some code that shows how to show a form.

private void button1_Click(object sender, EventArgs e)
{
    DimmerDialog dimmer = new DimmerDialog();
    dimmer.ShowForm(new Form2());
}

When you show a form, make sure that your form does not start any process (as a button click action for instance), because that process will run on your primary desktop and not on this desktop. It's best to keep things simple (like the XP shutdown dialog has) and to merely use the form to collect some data.

Class implementation

The class was written in mixed mode C++/CLI, but here's what the public interface looks like in C# (simulated - actual code is not in C#).

public class DimmerDialog
{
    public DimmerDialog();
    public void ShowForm(Form form);
    public void ShowMessageBox(string text, string title,
        MessageBoxIcon icon);
}

Here's the fade function I wrote (it's C++), where the final gray-scaling code is a rip out of one of  Christian's GDI+ articles. The fading algorithm is one I finalized on after some trial and error. It's far from perfect, but I thought this will do, considering the utility we get out of the fading effect.

Bitmap^ DimBitmap()
{
  if(m_ColorReductionStep == 0)
    return m_Image;
  Bitmap^ imagecopy = (Bitmap^)m_Image->Clone();
  BitmapData^ bmData = imagecopy->LockBits(
    System::Drawing::Rectangle(0, 0, 
    imagecopy->Width, imagecopy->Height), 
    ImageLockMode::ReadWrite, PixelFormat::Format24bppRgb); 
  BYTE* p = (BYTE*)bmData->Scan0.ToPointer();
  int nOffset = bmData->Stride - imagecopy->Width * 3; 
  BYTE red, green, blue;
  for(int y=0; y < imagecopy->Height; y++)
  {
    for(int x=0; x < imagecopy->Width; x++)
    {
      blue = p[0];
      green = p[1];
      red = p[2];

      switch(m_ColorReductionStep)
      {
      case 1:
        p[0]  = (BYTE)(.001 * red + .286 * green + .713 * blue);
        p[1]  = (BYTE)(.001 * red + .986 * green + .013 * blue);
        p[2]  = (BYTE)(.899 * red + .087 * green + .013 * blue);
        break;
      case 2:
        p[0]  = (BYTE)(.099 * red + .387 * green + .514 * blue);
        p[1]  = (BYTE)(.099 * red + .887 * green + .014 * blue);
        p[2]  = (BYTE)(.699 * red + .287 * green + .013 * blue);
        break;
      case 3:
        p[0]  = (BYTE)(.199 * red + .487 * green + .314 * blue);
        p[1]  = (BYTE)(.199 * red + .787 * green + .014 * blue);
        p[2]  = (BYTE)(.499 * red + .487 * green + .014 * blue);
        break;
      case 4:
        p[0] = p[1] = p[2] = (BYTE)(.299 * red + .587 * green + .114 * blue);
        break;
      }         
      p += 3;
    }
    p += nOffset;
  }
  imagecopy->UnlockBits(bmData);
  return imagecopy;
}

Don't even ask me why I used those fractions, I just got them after various attempts. Perhaps by modifying them, and by adding more steps (currently I use a 4-step fading), we might be able to get a smoother effect, but I didn't think it worth the effort.

History

  • Feb 23 2006 - Article first published.

License

This article, along with any associated source code and files, is licensed under The Common Development and Distribution License (CDDL)

About the Author

Nish Sivakumar
United States United States
Member
Nish is a real nice guy who has been writing code since 1990 when he first got his hands on an 8088 with 640 KB RAM. Originally from sunny Trivandrum in India, he has been living in various places over the past few years and often thinks it’s time he settled down somewhere.
 
Nish has been a Microsoft Visual C++ MVP since October, 2002 - awfully nice of Microsoft, he thinks. He maintains an MVP tips and tricks web site - www.voidnish.com where you can find a consolidated list of his articles, writings and ideas on VC++, MFC, .NET and C++/CLI. Oh, and you might want to check out his blog on C++/CLI, MFC, .NET and a lot of other stuff - blog.voidnish.com.
 
Nish loves reading Science Fiction, P G Wodehouse and Agatha Christie, and also fancies himself to be a decent writer of sorts. He has authored a romantic comedy Summer Love and Some more Cricket as well as a programming book – Extending MFC applications with the .NET Framework.
 
Nish's latest book C++/CLI in Action published by Manning Publications is now available for purchase. You can read more about the book on his blog.
 
Despite his wife's attempts to get him into cooking, his best effort so far has been a badly done omelette. Some day, he hopes to be a good cook, and to cook a tasty dinner for his wife.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
NewsC# users may find this helpfulmemberMember 419655026 Sep '09 - 8:32 
http://techneighbour.co.cc/blog/2009/09/dialogbox-imitating-windows-shutdown-dialog/[^]
GeneralI think XP SP3 might have broken thismemberjrizzo@langan.com30 Mar '09 - 9:33 
The code and sample application do not seem to work on my computer. I even tried the precompiled demo with the same result. I am running windows xp SP3. It compiles and runs just fine, but DimmerDialog::ShowForm() and DimmerDialog.ShowMessageBox() do not seem to do anything.
QuestionGreat;Possible to return DialogResult?memberMember 409275322 Jan '09 - 19:54 
Hi Nishant,
Great Piece o f code.Thanks for sharing. Is it possible ShowForm() method to return DialogResult?.it will be more useful for many dialogs in an application.
 
Thanks,
Mathi.
யாதும் ஊரே ; யாவரும் கேளிர் !
GeneralDoes not work in Vistamemberbobfox7 Aug '08 - 11:53 
Subject says it all.
GeneralRe: Does not work in Vistamembermayurmv4 Sep '08 - 5:03 
Use from http://developmentzone.blogspot.com[^]
GeneralRe: Does not work in Vistamembertom94 Jan '09 - 0:33 
The link is not working Frown | :(
 
Have someone a working link?
 
Thanks
QuestionVB6memberJohn Mackay14 Feb '07 - 15:52 
Hi,
I'm Not too familiar with the language used for this example, however I really do need something like this to help the non computer literate users of my application understand that they need to complete the foreground form prior to proceeding. Is there any way this can be used within VB6, I was thinking maybe calling a basic "FADE ONLY" application as a separate process (shell the programme perhaps) then adding my form over the top (I can then use API to kill the "FADE" application once the user has attended to the form)
I have searched the Web High and low for an example of how to convert the entire screen to Grey Scale and leave a single window as full colour within VB6 and so far found only one example (that I currently use) but this is very slow and uses lost Resources. Cry | :((
QuestionGrayed outmemberBillyDisMe21 Dec '06 - 10:49 
Do you believe it possible to persist the grayscale effect permanently? As a theme perhaps? Thanks.
Generalvisual basic 6 classicmemberTheCardinal4 Aug '06 - 1:21 
Is there a possiblity that this effect can be use in vb6? Smile | :)
 

 
-vb6 roots
-C# novice
-Power is reponsibility...

GeneralCoolmembercomputerguru9238225 Feb '06 - 7:59 

Very cool effect Smile | :)
 
Paul
GeneralRe: CoolstaffNishant Sivakumar2 Mar '06 - 5:58 
computerguru92382 wrote:
Very cool effect

 
Thanks man Smile | :)
 
Regards,
Nish
Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
The Ultimate Grid - The #1 MFC grid out there!

GeneralDual MonitorsmemberH0G4N24 Feb '06 - 0:37 
This code doesn't work on Dual Monitors. The second screen turns completely black.
GeneralRe: Dual MonitorsstaffNishant Sivakumar24 Feb '06 - 1:03 
H0G4N wrote:
This code doesn't work on Dual Monitors. The second screen turns completely black.

 
I am a miserable programmer who's never worked on more than a single monitor - neither at work nor at home! Cry | :((
 
How does the normal Shutdown dialog behave on a multiple monitor setup?
 
Regards,
Nish
Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
The Ultimate Grid - The #1 MFC grid out there!

GeneralRe: Dual MonitorsmemberH0G4N24 Feb '06 - 1:48 
Windows handles it fine, however most coders do not take Dual Moniters into consideration.
 
Most of the screensavers here at the codeproject only display on one screen with the normal desktop still showing on the other screen.
GeneralRe: Dual MonitorsstaffNishant Sivakumar24 Feb '06 - 2:10 
H0G4N wrote:
Windows handles it fine

 
Since I can't see how it is (since I only have one monitor) could you explain what you mean by "fine"? Does it show a background color on the 2nd monitor? Or does it show the gray scale capture of the primary monitor there? Or the gray scale capture of the second monitor?
 
H0G4N wrote:
however most coders do not take Dual Moniters into consideration.

 
Because they still work on a single monitor system (like me) Frown | :-(
 
Regards,
Nish
Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
The Ultimate Grid - The #1 MFC grid out there!

GeneralRe: Dual MonitorsmemberH0G4N24 Feb '06 - 3:27 
Fine as in "as expected". Fades into a nice grayscale of the current capture.
GeneralRe: Dual MonitorsstaffNishant Sivakumar24 Feb '06 - 3:28 
H0G4N wrote:
Fine as in "as expected". Fades into a nice grayscale of the current capture.

 
Thanks. I don't have a 2nd one as I mentioned, but I'll see if I can heuristically code for an unknown 2nd or 3rd monitor Smile | :)
 
Regards,
Nish
Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
The Ultimate Grid - The #1 MFC grid out there!

GeneralRe: Dual MonitorsmemberH0G4N24 Feb '06 - 3:41 
That would be good. Wasn't a criticism of your code. It's just something that people should be aware of.
GeneralRe: Dual MonitorsstaffNishant Sivakumar24 Feb '06 - 4:44 
H0G4N wrote:
That would be good. Wasn't a criticism of your code. It's just something that people should be aware of.

 
Actually, I very much appreciate your feedback. Until today, I never even considered the multiple monitor aspect since I've never worked on more than a single monitor.
 
Regards,
Nish
Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
The Ultimate Grid - The #1 MFC grid out there!

GeneralRe: Dual MonitorssitebuilderMichael Dunn2 Mar '06 - 20:56 
When you create the bitmap, you get the size with GetSystemMetrics(SM_CXSCREEN) and GetSystemMetrics(SM_CYSCREEN). Those return the size of the primary monitor, not the entire virtual desktop. Use SM_CXVIRTUALSCREEN and SM_CYVIRTUALSCREEN instead.
Then in the BitBlt() call, you use (0,0) as the source top-left coordinate, but that may not be the coordinate of the top-left of the virtual desktop. You can get that coordinate by passing SM_XVIRTUALSCREEN and SM_YVIRTUALSCREEN to GetSystemMetrics().
 
--Mike--
Visual C++ MVP Cool | :cool:
LINKS~! Ericahist | NEW!! PimpFish | CP SearchBar v3.0 | C++ Forum FAQ
GeneralRe: Dual MonitorsstaffNishant Sivakumar3 Mar '06 - 1:09 
Thanks Mike.I don't have dual monitors though - which is a real pity Frown | :-(
While I thought of it, I didn't want to use code that I couldn't really test, and I even googled for some app, that'd simulate multiple desktops on a single desktop, using some display driver addition or something - didn't get anything useful Frown | :-(
 
Regards,
Nish
Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
The Ultimate Grid - The #1 MFC grid out there!
 
-- modified at 7:09 Friday 3rd March, 2006
Generalguuuuuudmembertoxcct23 Feb '06 - 23:16 
too bad it's MC++ Laugh | :laugh:
 
any plan to port this to MFC dear Nish ?! Wink | ;)
 
very good article anyway !
 

TOXCCT >>> GEII power
[toxcct][VisualCalc 2.24][3.0 soon...]
GeneralRe: guuuuuudstaffNishant Sivakumar24 Feb '06 - 1:04 
toxcct wrote:
very good article anyway !

 
Thanks Man Smile | :)
 
toxcct wrote:
too bad it's MC++
 
any plan to port this to MFC dear Nish ?!

 
Nope - trying to focus on .NET now Roll eyes | :rolleyes:
 
Regards,
Nish
Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
The Ultimate Grid - The #1 MFC grid out there!

GeneralNo desktop switchingmemberThomas Weidenmueller23 Feb '06 - 12:44 
Just for the record: The windows dialog doesn't switch to the secured winlogon desktops.
GeneralRe: No desktop switchingstaffNishant Sivakumar23 Feb '06 - 12:52 
Thomas Weidenmueller wrote:
Just for the record: The windows dialog doesn't switch to the secured winlogon desktops.

 
If that's so, do you have any source of information to point me to?
 
Regards,
Nish
Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
The Ultimate Grid - The #1 MFC grid out there!

GeneralRe: No desktop switchingmemberThomas Weidenmueller23 Feb '06 - 13:33 
Just press Alt+tab while the dialog is displayed. It means you're on the same desktop as the other windows.
GeneralRe: No desktop switchingmemberRama Krishna Vavilala23 Feb '06 - 13:45 
OMG | :OMG: OMG | :OMG:
 
That's interesting I never knew that you can press ALT+TAB when the shutdown dialog box is shown. I never tried. How come it never occured to me?
 


Member in good standing - the great cult of Firefox at CP
GeneralRe: No desktop switchingstaffNishant Sivakumar23 Feb '06 - 14:02 
Rama Krishna Vavilala wrote:
That's interesting I never knew that you can press ALT+TAB when the shutdown dialog box is shown. I never tried. How come it never occured to me?

 
Same here - never tried that out Smile | :)
 
Regards,
Nish
Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
The Ultimate Grid - The #1 MFC grid out there!

GeneralRe: No desktop switchingstaffNishant Sivakumar23 Feb '06 - 14:02 
Thomas Weidenmueller wrote:
Just press Alt+tab while the dialog is displayed. It means you're on the same desktop as the other windows.

 
Holy crap! That is correct! I never tried Alt-Tab before Sigh | :sigh:
I'll update the article and remove the incorrect text.
 
Thanks, Thomas.
 
Regards,
Nish
Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
The Ultimate Grid - The #1 MFC grid out there!

GeneralRe: No desktop switchingmembermr.stick24 Feb '06 - 1:19 
LOL! Why have I never tried that either?!?!
 
C
GeneralRe: No desktop switchingstaffNishant Sivakumar24 Feb '06 - 2:11 
mr.stick wrote:
LOL! Why have I never tried that either?!?!

 
Yeah, it's not something you'd automatically try, eh? Smile | :)
 
Regards,
Nish
Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
The Ultimate Grid - The #1 MFC grid out there!

GeneralRe: No desktop switchingstaffNishant Sivakumar23 Feb '06 - 14:06 
Article text has been updated. Thanks again.
 
Regards,
Nish
Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
The Ultimate Grid - The #1 MFC grid out there!

GeneralThat's some interesting codeprotectorMarc Clifton23 Feb '06 - 12:03 
And staring at it, I couldn't figure out why:
 
1) the switch statement is is reverse order
2) the fourth case, colorReductionStep==4, is tested for in an if statement, rather than putting it in as a case.
 
Maybe I'm missing something?
 
Also, instead of four discrete steps, you could make a nice linear fade by calculating the luminosity of the pixel (probably factoring RGB perceived intensity differences) and then determining the target gray scale for the same luminosity. I'm sure there's actually a standard equation to make a color image gray. In fact, doesn't Christian have a function that does that? Then you'd get the nice smooth transition that Windows has.
 
One more question--why would one use this affect to indicate a "very important message box or form that requires immediate user attention"? I always laughed the XP fade, as it fades to gray, but then when you click on "ShutDown", the colors return. Ridiculous. Gray is also not as visible as color. What's wrong with the hand or exclamation icon? Just my personal opinion on UI design and not intended to be a reflection on your article.
 
Marc
 
Pensieve

GeneralRe: That's some interesting codestaffNishant Sivakumar23 Feb '06 - 12:20 
Marc Clifton wrote:
1) the switch statement is is reverse order

 
The code evolved a lot while I tried to get the fade right. Eventually once I got it right, I left it like that - while it's not common, a reverse order switch works okay I guess Smile | :)
 
Marc Clifton wrote:
2) the fourth case, colorReductionStep==4, is tested for in an if statement, rather than putting it in as a case.

 
Again, a result of code evolution. The original code required an if-check. I guess I should clean this up a little - not that it particularly affects things - just weird to look at I guess/
 
Marc Clifton wrote:
Also, instead of four discrete steps, you could make a nice linear fade by calculating the luminosity of the pixel (probably factoring RGB perceived intensity differences) and then determining the target gray scale for the same luminosity. I'm sure there's actually a standard equation to make a color image gray. In fact, doesn't Christian have a function that does that? Then you'd get the nice smooth transition that Windows has.

 
Does he? I looked around for something like that and couldn't find one. If there's a better algorithm that gives a smoother fade, I'd definitely like to use that. It should be fast though - some of the earlier code I tried took 7-8 seconds to render. (I admit to using GetPixel Blush | :O for the first version).
 
Marc Clifton wrote:
One more question--why would one use this affect to indicate a "very important message box or form that requires immediate user attention"? I always laughed the XP fade, as it fades to gray, but then when you click on "ShutDown", the colors return. Ridiculous. Gray is also not as visible as color. What's wrong with the hand or exclamation icon? Just my personal opinion on UI design and not intended to be a reflection on your article.

 
I personally do not favor this sort of behavior. But these days, apps try their best to look as similar to Windows or Office as possible. For instance, when the next Office is out, we are gonna have lots of apps using that ribbon control, just like how today, a lot of apps use the Off 2003 style menu system and gradient shading.
 
I've been doing some C#/.NET coding the last couple of weeks just to get back to being familiar with it - and this article and the last one are the results of that. Thanks for the feedback, Marc.
 
Regards,
Nish
Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
The Ultimate Grid - The #1 MFC grid out there!

AnswerRe: That's some interesting codememberWilli Deutschmann24 Feb '06 - 5:48 
Nishant,
 
I like your approach to just curtain the "real" desktop with its own screenshot and then alter this one instead.
Concerning your fading algorithm. The "right" way to convert color to its corresponding grey value is a weighted mean value based on the different sensitivity of the human vision in the red, green and blue channel. The human eye is especially sensitive to green colors (probably because nature used to be mostly green) and least sensitive to blue. So the weights of the single channels have accordingly been defined as follows (my numbers differ slightly from yours, but in the end I doubt it would make a significant difference):
 
grey = 0.2126*red + 0.7152*green + 0.0722*blue
 
what you want to do now is find a function which lets you approach this ratio step by step.
(You appear to be doing this in four discreet steps already, having found the values by trial and error if I got you correctly Smile | :) ).
Now for example, let a variable "a" run from 0.0 to 1.0 in steps that you define and calculate the resulting channels like the following:
 
red_i = (1.0-a*(1.0-0.2126))*red + 0.7152*a*green + 0.0722*a*blue
green_i = 0.2126*a*red + (1.0-a*(1.0-0.7152))*green + 0.0722*a*blue
blue_i = 0.2126*a*red + 0.7152*a*green + (1.0-a*(1.0-0.0722))*blue
 
I havent actually tested these equations, but if you simply put a=0 you get a direct mapping red_i==red, green_i==green and blue_i==blue. If you set a=1 you will arrive at the above formula. So it should work and you should be able to replace your switch statement with a loop and run it with a resolution of your preference.
 
Hope it helps and thanks again for the article!
GeneralRe: That's some interesting codesitebuilderShog93 Mar '06 - 6:03 
Nishant Sivakumar wrote:
f there's a better algorithm that gives a smoother fade, I'd definitely like to use that. It should be fast though - some of the earlier code I tried took 7-8 seconds to render. (I admit to using GetPixel Blush | :O for the first version).

Use the algorithm Willi Deutschmann posted for calculating gray, if it's too slow then build a look-up table. Smile | :)

 

----
Bots don't know when people die.
--Paul Watson, RIP

GeneralRe: That's some interesting codemembertombala18 Mar '06 - 17:45 
Uhm, am I missing something? If you're getting back to C#, why use any C++ code at all, mixed or straight up? You could do the same stuff using pure C#. For example you could look at ColorMatrix for creating B&W conversion. You won't need to do any looping at all using ColorMatrix. With one call, poof, your image has a B&W copy.
 
T.
GeneralRe: That's some interesting codestaffNishant Sivakumar23 Feb '06 - 12:33 
Alright - fixed the weird switch and the unwanted if Smile | :)
 
There's a risk that some people would copy/paste this code, and when their bosses ask them where they got that weird looking switch block from, I sure don't want it traced back to me.
 
Thanks again, Marc Smile | :)
 
Regards,
Nish
Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
The Ultimate Grid - The #1 MFC grid out there!

GeneralRe: That's some interesting codeprotectorMarc Clifton23 Feb '06 - 12:59 
Nishant Sivakumar wrote:
I sure don't want it traced back to me.

 
LOL! Or, as happened to me, when I discovered that a client, who had hired me as a consultant, had taken my code, BSD Licensed, and removed the license agreement (in violation of the BSD licence) but left certain key "signatures" of my code in the code. Like a comment I had made regarding a contribution leppie made to the code. And the client? Xamlon. Big Grin | :-D
 
Marc
 
Pensieve

GeneralRe: That's some interesting codestaffNishant Sivakumar23 Feb '06 - 13:00 
Marc Clifton wrote:
And the client? Xamlon.

 
Did you let them have it?
 
Regards,
Nish
Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
The Ultimate Grid - The #1 MFC grid out there!

GeneralRe: That's some interesting codeprotectorMarc Clifton23 Feb '06 - 13:15 
Nishant Sivakumar wrote:
Did you let them have it?

 
As in, "sock-it-to-them"? No. As in "let them have the code", yes, but never formally. I just let it slide and filed it under "nice people, eh?"
 
Marc
 
Pensieve

GeneralRe: That's some interesting codestaffNishant Sivakumar23 Feb '06 - 14:07 
Marc Clifton wrote:
As in, "sock-it-to-them"? No.

 
Yep, that's what I meant.
 
Marc Clifton wrote:
As in "let them have the code", yes, but never formally. I just let it slide and filed it under "nice people, eh?"

 
Okay, makes sense, considering they were contracting you at that time.
 
Regards,
Nish
Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
The Ultimate Grid - The #1 MFC grid out there!

GeneralRe: That's some interesting codeprotectorMarc Clifton23 Feb '06 - 15:56 
Nishant Sivakumar wrote:
Okay, makes sense, considering they were contracting you at that time.

 
Well, it was a timing thing--they had clearly incorporated the code before I was contracted.
 
Marc
 
Pensieve

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 23 Feb 2006
Article Copyright 2006 by Nish Sivakumar
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid