Greg Dolley’s Weblog

A Blog about Graphics Programming, Game Programming, Tips and Tricks

  • Archives

  • June 2023
    M T W T F S S
     1234
    567891011
    12131415161718
    19202122232425
    2627282930  
  • Blog Stats

    • 1,071,665 hits
  • Subscribers

  • Twitter

Archive for the ‘General Programming’ Category

How to Make a C# Application Without the Wizard

Posted by gregd1024 on February 14, 2008

Most C++ programmers know how to start coding from an empty project without the wizard’s assistance. But how many tutorials show a way to do this in C#? Questions arise like what references you need, what should the default project settings be, etc.

In this post I’m going to create a Windows Form application starting from scratch (just an empty project). It’s actually quite easy if you’re making a DLL, Console application, or Forms application. Plus, you can be certain that your application doesn’t contain any useless references or dependencies.

Note: this tutorial is applicable to Visual Studio 2008.

Step 1 – Create an Empty Project

Start Visual Studio and select “File->New Project.” When the “New Project” dialog appears, select the “Empty Project” template and name it whatever you like. Click OK.

c_sharp_app_from_scratch_new_project_dialog

Step 2 – Modify Project Settings

At this point you’ll have an empty project loaded in Solution Explorer without any source files or references listed. Now, go to the “Project” menu and select “Properties.” Under the “Application” tab, click the “Output type” combo box and change it from “Console Application” to “Windows Application.” This makes the project into a regular Windows Form app.

c_sharp_app_from_scratch_project_settings

Save this configuration (hit CTRL-S or click “File->Save”) and close the “Project Settings” window.

Step 3 – Add References

Now right click on the “References” folder in Solution Explorer and click “Add Reference” (you can also select the same option from the “Project” menu). Which references you’ll need will depend on what kind of project you’re building, but in our case we need “System,” “System.Windows.Forms,” and “System.Drawing.” They are located in the .NET tab of the “Add Reference” dialog:

c_sharp_app_from_scratch_system_reference

After you’ve selected all three references, click OK. Now your project should look like this in Solution Explorer:

 c_sharp_app_from_scratch_solution_explorer_references

FYI: for almost any project you’ll at least need the “System” reference, so I add this one right away no matter what kind of project I’m creating. If your project was extremely simple, had no dependencies, and you didn’t care about fully qualifying your types, then you could get away with not adding this reference.

Step 4 – Add a Source File

You’ll notice from the last screenshot that we don’t have any source files in our project. Well that’s easy to fix – click on “Add New Item” located under the “Project” menu. When the “Add New Item” dialog appears, select “Code File.” Name it whatever you like and click OK.

c_sharp_app_from_scratch_add_code_file

Step 5 – Add Code

We didn’t want to select the “Class” template because that would cause Visual Studio to create a class skeleton and add useless references to the project.  Selecting “Code File” ensures that nothing is done which isn’t completely necessary. It also gives us an entirely blank source file. Here is the minimum amount of code you’ll have to add for some meaningful output:

  1. Type the “using” directives for “System,” “System.Windows.Forms,” and “System.Drawing.”
  2. Type a namespace declaration.
  3. In that namespace type a class declaration deriving from “Form”.
  4. Type a “static void Main()” function into the class.
  5. Inside the Main() function type this line: “Application.Run(new MyClass());”

After following the steps above, your code should look similar to this:

using System;
using System.Windows.Forms;

using System.Drawing;

 

namespace MyProject
{
   class MyClass:Form
   {
      static void Main()
      {
         Application.Run(new MyClass());
      }
   }
}

You can actually compile and run the project in this state, but it will just produce a blank form and you won’t be able to add controls in the Designer. We’ll take care of this problem in the next step.

Step 6 – Add Controls to Form

You may be wondering how to associate your hand-written code with Visual Studio’s Designer. Believe it or not, there’s no need to do this. In fact, Visual Studio automatically detects whenever you derive a class from “System.Windows.Forms.Form” and links the associated source file to the Designer.

Now, right click on your source file in Solution Explorer and select “View Designer.” When the Designer comes up you’ll see an empty form. Drag a button control on it and switch back to code-view. You’ll notice that Visual Studio has added this function to your class:

private void InitializeComponent()
{
   this.button1 = new System.Windows.Forms.Button();
   this.SuspendLayout();
   //
   // button1
   //
   this.button1.Location = new System.Drawing.Point(104, 93);
   this.button1.Name = “button1”;
   this.button1.Size = new System.Drawing.Size(75, 23);
   this.button1.TabIndex = 0;
   this.button1.Text = “button1”;
   this.button1.UseVisualStyleBackColor = true;
   //
   // MyClass
   //
   this.ClientSize = new System.Drawing.Size(284, 264);
   this.Controls.Add(this.button1);
   this.Name = “MyClass”;
   this.ResumeLayout(false);

}

Visual Studio automatically keeps InitializeComponent() up-to-date. It contains all the code for creating and positioning the form’s controls. However, we still have to call the function. For this, we turn to the class’s constructor. Since we haven’t defined a constructor yet, we’ll do it now and add the call to InitializeComponent():

MyClass()
{
   InitializeComponent();
}

By now, your source code should look like this:

using System;
using System.Windows.Forms;
using System.Drawing;

 

namespace MyProject
{
   class MyClass:Form
   {
      private Button button1;
     

      MyClass()
      {
         InitializeComponent();
      }
     

      static void Main()
      {
         Application.Run(new MyClass());
      }

     

      private void InitializeComponent()
      {
         this.button1 = new System.Windows.Forms.Button();
         this.SuspendLayout();
         //
         // button1
         //
         this.button1.Location = new System.Drawing.Point(104, 93);
         this.button1.Name = “button1”;
         this.button1.Size = new System.Drawing.Size(75, 23);
         this.button1.TabIndex = 0;
         this.button1.Text = “button1”;
         this.button1.UseVisualStyleBackColor = true;
         //
         // MyClass
         //
         this.ClientSize = new System.Drawing.Size(284, 264);
         this.Controls.Add(this.button1);
         this.Name = “MyClass”;
         this.ResumeLayout(false);

      }
   }
}

Step 7 – Compiled and Run

Now try running the project! Hopefully you see something similar to my output:

c_sharp_app_from_scratch_output_form

Congratulations! You just created a Windows Forms application from scratch!

Optional Things

You may be thinking, “but what about the extra code the wizard adds in forms like Dispose() and the “components” member? Don’t I need that stuff too?” The short answer: it depends.

In certain situations you’ll need the “components” member, but it’s not necessary to define it. The Designer will add the declaration when it’s needed. Try placing a Notify Icon or Timer control and you’ll see what I mean. The “components” member is used for most of the non-visual controls available in the Designer. If you drag a control on a form and it gets added to the container bar (on the bottom of the design window) instead of making some visual appearance on the form itself, then there’s a good chance it’ll use this variable.

You’ll need the Dispose() function only if you must explicitly free resources that can’t otherwise be managed by the Garbage Collector. These resources might be unmanaged memory, file handles, database connections, or similar objects who’s destruction is non-deterministic. Given that our example program allocated objects only from the managed heap, having a Dispose() would be pointless.

If you find that your class will eventually need the “components” member and a Dispose() method, here’s the minimum amount of code you’ll need to get started:

// Special Designer variable
private System.ComponentModel.IContainer components = null;

 

// Used to explicitly free any resources not
// managed by the Garbage Collector
protected override void Dispose(bool disposing)
{
   if (disposing && (components != null))
   {
      components.Dispose();
   }
   base.Dispose(disposing);
}

Also, you may have noticed that when using the wizard to generate a project, it creates a separate form class instead of using the application’s main class as the container. This results in two extra source files being added to the solution. You can do this yourself by creating one source file giving it a “.cs” extension (such as “Form.cs”) and creating another file with the same name but giving it a “.Designer.cs” extension (such as “Form.Designer.cs”). Visual Studio will automatically associate these two files together and you’ll see “Form.Designer.cs” underneath “Form.cs” in Solution Explorer’s tree view:

c_sharp_app_from_scratch_manual_form_files

Conclusion

I hope that this post has given you insight into rolling your own Windows Forms project from scratch. While it will always be faster to use the wizard, at least now you don’t have to rely on it. You also know what parts of the wizard’s code can be deleted if your program doesn’t require it.

-Greg Dolley

*Get new posts automatically! Grab the RSS feed here. Want email updates instead? Click here.

Advertisement

Posted in C# Programming, General Programming, Tips and Tricks | 6 Comments »

How to Convert a Console App into a Windows App in C# – Part Two

Posted by gregd1024 on February 9, 2008

As I promised in yesterday’s post, I’m now going to show you an even easier way to convert a C# console application into a regular Windows application. Since the steps are nearly identical, I’m just going to focus on the key points instead of writing the same thing as before.

First, perform the following steps:

  • Create a regular C# console application or open one of your own.
  • Add the following two references to your project and the corresponding “using” statements on top of the main source file:

using System.Drawing

using System.Windows.Forms

  • Remove the “args” string array parameter from the Main() function.
  • Add “Application.EnableVisualStyles();” as the first call in the Main() function.
  • Change the “Output type” of your project from “Console Application” to “Windows Application.”

Now for the fun part (the part that’s different from my last post). Do the following:

  • Change the “Program” class to derive from “System.Windows.Forms.Form.”
  • Add “Application.Run(new Program());” as the last call in the Main() function.

At this point your “Program” class should look like this:

class Program:System.Windows.Forms.Form

{

   static void Main()

   {

      Application.EnableVisualStyles();

      Application.Run(new Program());

   }

}

We’re almost done. In fact, you can run the program now and you’ll see a blank form. But you won’t be able to place any controls on it. Well, actually that’s not true – you can place controls, but the form will still be blank at runtime. The last step is:

  • Add a constructor to the “Program” class and call “InitializeComponent()” inside it:

class Program:System.Windows.Forms.Form

{

   Program() // ADD THIS CONSTRUCTOR

   {

      InitializeComponent();

   }

 

   static void Main()

   {

      Application.EnableVisualStyles();

      Application.Run(new Program());

   }

}

“InitializeComponent()” will not be defined yet. However, the Form Designer will create this function as soon as any control is placed on the form or its layout is modified. You may have noticed that the icon next to “Program.cs” (in Solution Explorer) has changed to a form instead of the one representing a code file:

console_convert_2_icon_change 

This means you can double-click on it and Visual Studio will open the Form Designer instead of going to the source. Try this:

  1. Double click on Program.cs.
  2. Change the form’s size in the Designer.
  3. Go back to the source window of Program.cs.

Now you should see the “InitializeComponent()” function defined underneath “Main().” Your “Program” class will now look like this:

class Program:System.Windows.Forms.Form
{
   Program()
   {
      InitializeComponent();
   }
     
   static void Main()
   {
      Application.EnableVisualStyles();
      Application.Run(new Program());
   }

 

   private void InitializeComponent() // DESIGNER WILL ADD THIS FUNCTION
   {
      this.SuspendLayout();
      //
      // Program
      //
      this.ClientSize = new System.Drawing.Size(367, 188);
      this.Name = “Program”;
      this.ResumeLayout(false);

 

   }
}

You’re done! 🙂 Everything is contained in this one source file. The designer will keep on modifying “InitializeComponent()” whenever something changes in the form itself. It will also add the necessary member variables to the “Program” class whenever controls are placed on the form.

-Greg Dolley

*Get new posts automatically! Grab the RSS feed here. Want email updates instead? Click here.

Posted in C# Programming, General Programming, Tips and Tricks | 22 Comments »

How to Convert a Console App into a Windows App in C#

Posted by gregd1024 on February 8, 2008

In this post I’m going to demonstrate how you can easily take a simple C# console application and convert it into a regular Windows application. It will involve just a few code changes and one project settings change. There are actually two methods to do it – a method in which you end up with almost the same code the wizard normally generates, and a method in which your application class becomes the main form. I’m only going to demonstrate the first method in this post; I’ll cover the second method in my next post.

The instructions presented in this post are for Visual Studio 2008, but most should work in a similar way with previous versions. I’m also going to use Express for the programmers who don’t have full blown Visual Studio.

Step 1: Create a C# Console Application

For demonstration purposes I’m creating a C# console application from the wizard. Of course, if you already have a console app you want to convert, open your project instead.

console_app_conversion_new_project

Step #2: Add References

Add the following references to the project:

  1. “System.Drawing”
  2. “System.Windows.Forms”

console_convert_add_references

These references are not added by the console app generator wizard, so we must add them manually. Also, add the corresponding “using” statements to your application’s main source file (the file that contains the Main() function):

  1. “using System.Drawing”
  2. “using System.Windows.Forms”

Step Three: Modify the Main() Function

Perform the following steps to the Main() function:

  1. Remove the “args” parameter from Main().
  2. Add the following two lines:

static void Main()

{

   Application.EnableVisualStyles(); // <– ADD THIS LINE

  

   // your existing code goes here (if any)

 

   Application.Run(new Form1()); // <– ADD THIS LINE

}

You can optionally add “Application.SetCompatibleTextRenderingDefault(false);” right under the EnableVisualStyles() call, but it’s not required. I mention it because this is what the wizard adds when auto-generating a project, but its purpose is beyond me (if you know what this function does, please leave a comment).

Step Four: Add a New Form Resource to the Project

Add a new form to the project and keep the name as Form1.cs:

console_convert_add_form

Step Five: Modify Project Settings

To modify the project settings go to the Project menu and click on Properties. Under the first tab (Application), click the Output type drop-down box and change it from “Console” to “Windows Application.”

console_convert_project_settings

Step Six: Compile and Run!

We’re done! 🙂 Now try running the project. You should see a blank form without any console box:

console_convert_up_and_running

Conclusion

In my next post I’m going to show you an even simpler way of doing this very same thing. Instead of explicitly adding a Form resource to the project, we’ll just take the class which houses Main() and turn it into a form programmatically. You’ll even be able to use the Form Designer to add controls and modify layouts.

-Greg Dolley

*Get new posts automatically! Grab the RSS feed here. Want email updates instead? Click here.

Posted in C# Programming, General Programming, Tips and Tricks | 17 Comments »

How to Fix – "C2039: ‘GetCurrentDirectoryA()’ : is Not a Member of ‘System::IO::Directory’"

Posted by gregd1024 on January 10, 2008

Have you ever received either one of these annoying error messages from the MSVC++ 9.0 compiler?

“C2039: ‘GetCurrentDirectoryW’ : is not a member of ‘System::IO::Directory'”

“C2039: ‘GetCurrentDirectoryA’ : is not a member of ‘System::IO::Directory'”

You’ll get this error when converting a native C++ project to a MC++ (managed) project and somewhere in your code there is a call to Directory::GetCurrentDirectory(). Below is a very simple example:

#include “stdafx.h”

#include <windows.h>

 

using namespace System;
using namespace System::IO;

 

int main(array<System::String ^> ^args)
{
    Console::WriteLine(L”Dir: “+Directory::GetCurrentDirectory()); // Error!
    Console::ReadKey();
    return 0;
}

The reason for the error is that “GetCurrentDirectory” is also defined as a macro in windows.h. The macro expands to “GetCurrentDirectoryA” or “GetCurrentDirectoryW.” So in the example above, the compiler actually sees “Directory::GetCurrentDirectoryW” which obviously isn’t defined in the “Directory” class.

The fix is simple – just “#undef” the macro:

#include “stdafx.h”

#include <windows.h>

 

using namespace System;

using namespace System::IO;

 

#undef GetCurrentDirectory

 

int main(array<System::String ^> ^args)

{
    Console::WriteLine(L”Dir: “+Directory::GetCurrentDirectory()); // OK

    Console::ReadKey();

    return 0;

}

Now the compiler sees the real “GetCurrentDirectory” function and there are no compile errors. 🙂

-Greg Dolley

Subscribe via RSS here. Want email updates instead? Click here.

Posted in General Programming, Tips and Tricks | 5 Comments »

How to Fix Visual Studio Bug: "’/RTC1′ and ‘/clr’ Options are Incompatible"

Posted by gregd1024 on December 31, 2007

Have you ever received this error when converting a native C++ project to MC++?

1>cl : Command line error D8016 : ‘/RTC1’ and ‘/clr’ command-line options are incompatible

While, yes, it’s true that ‘/RTC1’ (basic runtime checking) with ‘/clr’ (.NET support) are incompatible options, the problem is there’s no place in the Visual Studio IDE to turn off ‘/RTC1’ once it’s set (not even from the command line editor). The Project Settings dialog just lists different modes of runtime checking without a “disable” option:

basic_runtime_checks_image

In order to fix this problem, follow these steps:

  • Open up your “vcproj” file in a regular text editor.
  • Search for all the strings that look like:

BasicRuntimeChecks=”3″

  • Replace all instances with this string:

BasicRuntimeChecks=”0″

In your project file the “BasicRuntimeChecks” variable may not necessarily equal “3.” It just happened to be the default in my project. Whatever number appears as your default just replace it with “0” and that should fix the problem.

-Greg Dolley

Subscribe via RSS here. Want email updates instead? Click here.

Posted in General Programming, Tips and Tricks | 8 Comments »

"Decimal" .NET Type vs. "Float" and "Double" C/C++ Type

Posted by gregd1024 on December 10, 2007

Have you ever wondered what is the difference between the .NET “Decimal” data type and the familiar “float” or “double”? Ever wonder when you should one versus the other? In order to answer these questions, take a look at the following C# code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace IEEE_Floating_Point_Problems
{
   class Program
   {
      static void Main(string[] args)
      {
         int iteration_num = 1;
         
         Console.WriteLine("First loop, using float type:");
         
         // runs only four times instead of the expected five!
         for(float d = 1.1f; d <= 1.5f; d += 0.1f)
         {
            Console.WriteLine("Iteration #: {0}, float value: {1}", iteration_num++, d.ToString("e10"));
         }
         
         Console.WriteLine("\r\nSecond loop, using Decimal type:");
         
         // reset iteration count
         iteration_num = 1;
         
         // runs correctly for five iterations
         for(Decimal d = 1.1m; d <= 1.5m; d += 0.1m)
         {
            Console.WriteLine("Iteration #: {0}, Decimal value: {1}", iteration_num++, d.ToString("e10"));
         }
         
         Console.WriteLine("Press any key to continue...");
         Console.ReadKey();
      }
   }
}

Here is what the output looks like:

IEEE_float_problem_pic

At first glance, looking at the code and not the output, it seems like the first for() loop should run for five iterations. After all, there are five values from 1.1 up to and including 1.5 stepping by 0.1 (i.e. 1.1, 1.2, 1.3, 1.4, and 1.5). But in reality, the loop only runs through four iterations. Why is this? Also, why was 1.10000002 assigned as the first value of “d” instead of the hard-coded 1.1? The reason is simple – we’re working on hardware that uses binary floating point representation as opposed to decimal representation. Binary floating point is really an approximation of the true decimal number because it is base two (binary) instead of base 10 (decimal).

In order to understand this better, we’ll take the common (IEEE 754) floating point formula but use base 10 instead of two:

image

Filling in the variables to represent a value of 1.1 we get:

+1 * (1 + 0.1) * 10^0 =

        (1 + 0.1) * 10^0 =

                 1.1 * 10^0 =

                       1.1 * 1 = 1.1 <— Exactly the correct value

In the real base two version everything is the same except 10 changes to a two:

image

If you try to fill in this equation, you’ll immediately see the problem when converting 0.1 (the fraction part) into binary. Let’s do it here:

  • 0.1 x 2 = 0.2; so the binary digit is 0
  • 0.2 x 2 = 0.4; so the binary digit is 0
  • 0.4 x 2 = 0.8; so the binary digit is 0
  • 0.8 x 2 = 1.6; so the binary digit is 1
  • 0.6 x 2 = 1.2; so the binary digit is 1
  • 0.2 x 2 = 0.4; so the binary digit is 0
  • 0.4 x 2 = 0.8; so the binary digit is 0
  • 0.8 x 2 = 1.6; so the binary digit is 1
  • 0.6 x 2 = 1.2; so the binary digit is 1
  • 0.2 x 2 = 0.4; so the binary digit is 0
  • 0.4 x 2 = 0.8; so the binary digit is 0
  • 0.8 x 2 = 1.6; so the binary digit is 1
  • 0.6 x 2 = 1.2; so the binary digit is 1
  • and so on…

We end up with “0001100110011…” where the four digits at the end (0011) repeat forever. Therefore, it’s impossible to represent 0.1 with an exact binary number. If we can’t represent 0.1 exactly, then the rest of the equation will not evaluate precisely to 1.1; rather, it will be slightly more or slightly less depending on how many bits of precision you have available. This explains why the hard-coded “1.1” value changed slightly once assigned to the “d” variable. It can never be exactly 1.1 because the hardware is incapable of representing it.

These small precision errors get compounded in the first loop as 0.1 is added to “d” after each iteration. By the fifth time around “d” is slightly greater than 1.5 causing the loop to exit (the value of 1.5 can be represented exactly in binary and is not approximated). Therefore only four iterations are run instead of the expected five.

The .NET Decimal Type

So what’s the deal with this .NET “Decimal” type? It is simply a floating point type that is represented internally as base 10 instead of base two. Obviously with base 10 (our real-world numbering system) any decimal number can be constructed to the exact value without approximating. This is why the second for() loop runs for the expected five iterations and the variable “d” always has the exact hard-coded value assigned to it.

The Decimal type is really a struct (in C# and MC++) that contains overloaded functions for all math and comparison operations. In other words, it’s really a software implementation of base 10 arithmetic.

Which Type Should I Use?

Since Decimal types are perfectly accurate and float’s are not, why would we still want to use the intrinsic float/double types? Short answer – performance. In my speed tests Decimal types ran over 20 times slower than their float counterparts.

So if you’re writing a financial application for a bank that has to be 100% accurate and performance is not a consideration, use the Decimal type. On the other hand, if you need performance and extremely small floating point variations don’t affect your program, stick with the float and double types.

Other Considerations

Another thing the Decimal type can do that the float and double types cannot is encode trailing zero’s (note: there are some base two architectures, non-Intel, that can encode trailing zero’s – but those are out of the scope of this article). For example, there is a difference between 7.5 and 7.50 in the Decimal type, but there is no way to represent this in a standard float/double. Let’s look at another example – check out the following MC++ code:

#include "stdafx.h"
#include <stdio.h>

using namespace System;

int main(array<System::String ^> ^args)
{
   double number = 1.23+1.27;
   Console::WriteLine("double: {0}", number);
   
   Decimal decimal = (Decimal)1.23+(Decimal)1.27;
   Console::WriteLine("decimal: {0}", decimal);
   
   Console::WriteLine("Press any key to continue...");
   Console::ReadKey();

   return 0;
}

 

The first part that uses a double outputs 2.5, but the second one that uses a Decimal outputs 2.50 – we didn’t even have to specify a format string in order to get that trailing zero. This could be very useful in applications that deal with dollar amounts.

More Information

If you want to get more information regarding binary floating point versus decimal floating point, see this awesome FAQ by IBM:

http://www2.hursley.ibm.com/decimal/decifaq.html

Conclusion

I hope this has shed some light on the differences between the .NET Decimal type and the standard float/double types. If you have any questions or notice any typos in this article, please email me through my Contact page:

https://gregs-blog.com/contact

Thanks for reading! 🙂

-Greg Dolley

Posted in General Programming | 35 Comments »