Sunday, January 25, 2009

A simple StatusStrip Control Example using C#

C# StatusBar Example

Status bars play an important part in informing the user of the use of controls, the status of progress of the application etc. .Net provides a new control – the StatusStrip control – an extension of StatusBar

Let us have a small Windows form like the one as shown below.

Select the StatusStrip control in the ToolBox and drop it on the form




When you drop the control will be placed on the Tray below the form and a StatusStrip with a ToolStripLabel will be added to the Form






Now the ToolStripLabel can be used to apprise the user of the context and progress as shown below

private void buttonSelectXL_MouseHover(object sender, EventArgs e)

{

toolStripStatusLabel1.Text = "Click the Button to select the file";

}






.NET StatusBar Example, .NET ToolStripLabel Example

See also : Hide Excel Status Bar / Show Excel Status Bar using VBA

How to use C# MouseOver Events in Windows Forms

Yet again we take the good old select file form as our example. Let us use the MouseHover event of the ellipsis button to inform the user of its function.



To add an function to handle the event, click the event tab of the button and scroll to MouseHover event and double click it.

Add the following code to the event procedure.

private void buttonSelectXL_MouseHover(object sender, EventArgs e)

{

toolStripStatusLabel1.Text = "Click the Button to select the file";

}

The toolstrip label will be updated whenever the mouse pointer is hovered over the ellipsis button.





C# Array UBound Function

How to get the Upper Bound of an Array in C#

The upper bound of the array can be retrieved using the Length property as shown below:

private void GetUbound()

{

String[] arTemp = {"First","Second"};

MessageBox.Show (arTemp.Length.ToString ());

}

OpenFileDialog in C# - How to Use OpenFileDialog in C# Windows Application

Common Dialog in C# (.NET)

CommonDialog was widely used to select the files in Visual Basic 6.0. .Net provides a OpenFileDialog component, which can be used for the same.

Let us have a small Windows form where the file to process is to be selected. The form contains a CommandButton to invoke the Open File dialog box and a TextBox to display the selected file.





To use the OpenFileDialog, insert the component from Toolbox to the form



When it is droped to a form, the OpenFileDialog component appears in the tray at the bottom of the Windows Forms Designer.





Now write the following code in the Button’s Click event to display the Open file dialog box

private void buttonSelectXL_Click(object sender, EventArgs e)

{

openXLFile.Filter = "Microsoft Excel Workbooks (*.xls)*.xls";

if (openXLFile.ShowDialog() == DialogResult.OK )

{

String sFileName = openXLFile.FileName;

txtExcelFile.Text = sFileName;

}

else

{

MessageBox.Show("Please select a file");

}

}







The above code filers only Excel files in the Open Dialog Box

The selected file will be displayed in the Textbox


See also OpenFileDialog in Visual Basic .Net

For CommonDialog implementation in VB6.0 refer http://vbadud.blogspot.com/2007/06/visual-basic-common-dialog.html

How to Add Resources to C# Windows Application

How to add images as resources to C# Windows Application


Resources can be added to the C# Project using Resource Page in the Project Designer (Project à Project Properties)

The Resources page of the Project Designer hosts an instance of the Resource Designer that stores and maintains resources in a single location (Resources.resx).

The Resource Designer is language-neutral and supports projects in all Visual Studio languages. Items that you add to the project by using the Resource Designer are placed in the Resources directory for your project. The designer information is stored in a file named Resources.resx, and code for the resource is stored in Resources.Designer.cs, Resources.Designer.vb, or Resources.Designer.jsl.










Right Click the Resources section in the solution explorer and Select Add à Existing Item and select the Image files that need to be added






The images will be added as shown below






Drag the images to the Resources page – Rename the resource names if needed




Now you can use the Resources in your Form. Select the BackGroundImage from the Form’s properties box – Click on the ellipsis next to the BackGroundImage property. This will open the Select Resource dialog Box





Select appropriate resource from the list



The same can be set through code using

this.BackgroundImage = Properties.Resources.User_Single

For linkedresources see - Create HTML Message with Embedded Images in VB.NET / Embed images in HTML mail message using VB.NET









































Cannot find wrapper assembly for type library "Microsoft.Office.Core".

Cannot find wrapper assembly for type library "Microsoft.Office.Core".


There are updated custom wrappers available for the following referenced components: Office.

There are updated custom wrappers available for the following referenced components: Office.



The referenced component 'Microsoft.Office.Core' could not be found.

The referenced component 'Excel' could not be found.

The warning occurs when you open the C#/ VB.Net Solution referring a different version of Microsoft Excel / Office. For example, If you open the Project, which refers Excel 2003 (Excel 11.0 Library) in Excel 2007 machine



How to remove the Word from memory using C#

How to delete the leftover Word object using C#.

Closing Word Runtimes not removed by Word.Quit / Application.Quit

When Word crashes, it often takes with it the open documents. These documents will be write-locked and will appear as read-only to subsequent users. There are umpteen no. of reasons to crash a Word document and leave the ‘Winword.exe’ running in the memory. The following VB.NET code will remove the unused Word objects from memory.

Public Sub KillUnusedWordProcess()

Dim oXlProcess As Process() = Process.GetProcessesByName("Winword")

For Each oXLP As Process In oXlProcess

If Len(oXLP.MainWindowTitle) = 0 Then

oXLP.Kill()

End If

Next

End Sub

We have not tested the code in real-time. Our assumption was that any Word instance opened by user has a Window Title and programs using Word have been terminated. Check if the code is of any use and post the updations / suggestions to our ‘dud’ buddiesJ

automation does not close Microsoft Word, Application.Quit not closing Word

Excel Runtimes not removed by Excel.Quit / Application.Quit

How to delete the leftover Excel object using VB.NET / Vb.NET delete Excel from memory

Excel runtimes that remain after the program is a nemesis. Many times this might be due to the leftover Excel objects in the program that causes Excel to remain in memory even after Application.Quit. Workbooks that are modified and left open often causes this problem. We have tried out one method to get rid of the Excel in memory using Vb.NET. We assumed that the programs that used Excel has been terminated and if any Excel remains in the memory it should be of the ‘legitimate’ application that the user has opened or the left over Excel.

We checked the presence of Title for Excel Application, which was present in all cases for the open instance of Excel. Left over instances didn’t had the title. The following code ‘kills’ the instances of Excel in memory that don’t have a WindowTitle.

Public Sub KillUnusedExcelProcess()

Dim oXlProcess As Process() = Process.GetProcessesByName("Excel")

For Each oXLP As Process In oXlProcess

If Len(oXLP.MainWindowTitle) = 0 Then

oXLP.Kill()

End If

Next

End Sub

Try if it works for you and post your suggestions or modifications

Keywords : automation does not close microsoft excel, Application.Quit not closing Excel

Friday, January 16, 2009

No overload for method 'get_Range' takes '1' arguments

No overload for method 'get_Range' takes '1' arguments is error encountered by VB programmers trying to code in C#.

Excel.Workbook oWB = oXL.Workbooks.Open(sXLFileName, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing,missing );

// processing

Excel.Worksheet oWS = (Excel.Worksheet)oWB.Worksheets[1];

oWS.get_Range("A1").Value2 = "No";

This occurs when get_Range method is supplied with only one argument. Instead use any of the following:

oWS.get_Range("A1","A1").Value2 = "No";

or

Object missing = System.Type.Missing;

oWS.get_Range("A1",missing ).Value2 = "No";




Error Dialog

Non-invocable member 'Microsoft.Office.Interop.Excel._Workbook.Worksheets' cannot be used like a method.

Non-invocable member 'Microsoft.Office.Interop.Excel._Workbook.Worksheets' cannot be used like a method is a common error for a VB programmer working on C# projects. The error is solved when the round brackets are replaced with square ones

Excel.Worksheet oWS = (Excel.Worksheet)oWB.Worksheets(1);

To

Excel.Worksheet oWS = (Excel.Worksheet)oWB.Worksheets[1];


Error Message

Cannot implicitly convert type 'object' to 'Microsoft.Office.Interop.Excel.Worksheet'. An explicit conversion exists (are you missing a cast?)

Cannot implicitly convert type 'object' to 'Microsoft.Office.Interop.Excel.Worksheet'. An explicit conversion exists (are you missing a cast?) throws up when there is no Explicit casting - (Excel.Worksheet)

Excel.Worksheet oWS =oWB.Worksheets[1];

To

Excel.Worksheet oWS = (Excel.Worksheet)oWB.Worksheets[1];


Saturday, January 10, 2009

How to use Multithreading in C# Console Application

C# Multithreading Example – Continuous Alert

A query from our good blog friend SnakyJake led me to code a small multithreading stuff. The following example will torment the user with beeps till he/she inputs some value.

First let us create a small class that will handle the beeps

public class ClassBeep

{

private volatile bool EnoughBeeping;

public void StartBeeping()

{

while (!EnoughBeeping)

{

Console.Beep();

}

}

public void StopBeeping()

{

EnoughBeeping = true;

}

}

ClassBeep has two public methods, one to start beeping (and continuing) with it and another to stop the beep.

We also have a volatile variable EnoughBeeping which sets/resets the Beeps

This is quite simple. Isn’t it.

The next step is to code the main function to get the user input.

Wait a minute … here are the directives

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;

The last one “System.Threading” is the one we have added to the default directives.

Let us create an object for our Beep class

ClassBeep CBeep = new ClassBeep();

and create a thread and attach the function to it

Thread CBeepThread = new Thread(CBeep.StartBeeping);

We can now start the additional thread (worker thread)

CBeepThread.Start();

while (!CBeepThread.IsAlive) ;

Beep starts …

Now we can provide some instructions to the main thread

Thread.Sleep(1);

Console.WriteLine("Please enter the name");

string sText = Console.ReadLine();

int iLen = 0;

iLen = sText.Length;

while (iLen == 0)

{

sText = Console.ReadLine();

iLen = sText.Length;

}

The above loop will be executed till the user inputs a value.

Once the execution comes out of the loop, let us stop the beep and join the worker thread with the main one

CBeep.StopBeeping();

CBeepThread.Join();

Here is the full code of the main module

static void Main(string[] args)

{

ClassBeep CBeep = new ClassBeep();

Thread CBeepThread = new Thread(CBeep.StartBeeping);

CBeepThread.Start();

while (!CBeepThread.IsAlive) ;

Thread.Sleep(1);

Console.WriteLine("Please enter the name");

string sText = Console.ReadLine();

int iLen = 0;

iLen = sText.Length;

while (iLen == 0)

{

sText = Console.ReadLine();

iLen = sText.Length;

}

CBeep.StopBeeping();

CBeepThread.Join();

Console.WriteLine("Welcome {0}", sText);

}

Try it out. You can try overload of Beep Function to make your user have soothing and rhyming beeps as background.

Hope you get things done through beepsJ

Beep in C# Windows forms

Alert user with beep sound for invalid entries using C#

Many times when we alert the user with some messages but the user doesn’t heed immediately. A combination of sound and popup should be more helpful. The following example would alert the user if he/she hasn’t input the required field

private void buttonOK_Click(object sender, EventArgs e)

{

if (txtExcelFile.Text.Length == 0)

{

System.Console.Beep();

MessageBox.Show ("Select the file and continue...");

}

}



Windows User Form

For a Rhyming Beep peep at http://dotnetdud.blogspot.com/2009/01/how-to-create-rhyming-beeps-in-c.html

How to create Rhyming Beeps in C#

How to compose a tune using C#

Beep method is a simple instrument to create some wonderful tunes. I love music, but haven’t practiced or played. Hence I will stop posting the overloaded Beep function that can be ‘tuned’ for your use

Overloaded Console.Beep method takes two arguments

Console.Beep(int32 frequency, int32 duration)

Here is a way to do it

private static void RhymingBeeps()

{

int duration = 1000;

for (int i = 1500; i <= 2000; i = i +50)

{

Console.Beep(i, duration);

duration = duration / 2;

if (duration <>

{

duration = 1000;

}

}

}

Agreed! It is not that Rhyming. But post you are welcomed to post the rhyming ones here

Wednesday, January 7, 2009

Check if a String has Value using IsNullOrEmpty method

Check if a String has Value using IsNullOrEmpty method

IsNullOrEmpty is a convenience method that enables you to simultaneously test whether a String is nullNothingnullptra null reference (Nothing in Visual Basic) or its value is Empty.

Unlike the usual way to check twice (once for null and next for empty string), this method does it in a single check

private void CheckValue()

{

String s1 = null ;

String s2 = "";

if (String.IsNullOrEmpty(s1) == true)

{

MessageBox.Show("String does not hold any text");

}

}

This method actually checks if the Value is null or if the length of the string is Zero.

The left-hand side of an assignment must be a variable, property or indexer

The left-hand side of an assignment must be a variable, property or indexer

Assignment in conditional expression is always constant; did you mean to use == instead

The error mostly pops when a VB programmer codes in C#.

To fix this error, make sure that all operators are on the right-hand side and that the left-hand side is a variable, property, or indexer. Use == for checking values instead of ‘=’

if (String.IsNullOrEmpty(s1) == true)

instead of

if (String.IsNullOrEmpty(s1) = true)



How to set Default Button in Windows Form using C#

Default Button in Windows Forms using .NET

This property enables you to designate a default action to occur when the user presses the ENTER key in your application. The button assigned to this property must be an IButtonControl that is on the current form or located within a container on the current form.

You can use this property to allow the user to quickly navigate a simple form by allowing them to simply press the ENTER key when they are finished instead of manually clicking the accept button with their mouse.

The accept button might not be activated if the currently selected control on the form intercepts the ENTER key and processes it. For example, a multiline text box control allows the ENTER key to be pressed when it is selected to insert a new line character in the control.

this.AcceptButton = buttonOK;


Windows forms Accept Button

For doing the same in VB.Net
Refer : http://dotnetdud.blogspot.com/2007/06/vbnet-setting-default-cancel-buttons.html

And for doing the same in VB/VBA please refer : Setting Default & Cancel Buttons in VBA/Visual Basic

Cancel Button in Windows Forms (C#)

The cancel button for a form is the button control that is clicked whenever the user presses the ESC key. The button assigned to this property must be an IButtonControl that is on the current form or located within a container on the current form.

This property allows you to designate a default action to occur when the user presses the ESC key in your application. You can use this property to allow the user to quickly navigate a simple form by allowing them to simply press the ESC key to close a window without committing changes instead of manually clicking the cancel button with their mouse.

this.CancelButton = buttonCancel;


Cancel Button in Windows Forms (C#)


For setting the same in VBA/VB refer : http://vbadud.blogspot.com/2007/06/setting-default-cancel-buttons-in.html

See also Setting Default & Cancel Buttons in VBA/Visual Basic

How to use Existing Instance of Excel in C#



C# GetObject Method

Marshal.GetActiveObject gets a running instance of the specified object from the Running Object Table (ROT).

using System.Runtime.InteropServices;

using Excel = Microsoft.Office.Interop.Excel;

private void GetExcel()

{

try

{

oXL = (Excel.Application)Marshal.GetActiveObject("Excel.Application");

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}

}

Marshal.GetActiveObject exposes the GetActiveObject COM API method from OLEAUT32.DLL; however, the latter expects a class identifier (CLSID) instead of the programmatic identifier (ProgID) expected by this method. To obtain a running instance of a COM object without a registered ProgID, use platform invoke to define the GetActivateObject COM method


How to Disable Minimize Button on Windows Forms using C#

How to Disable Minimize Box on Windows Forms using C#

A Minimize button enables users to minimize a window to an icon. To display a Minimize button, you must also set the form's FormBorderStyle property to FormBorderStyle.FixedSingle, FormBorderStyle.Sizable, FormBorderStyle.Fixed3D, or FormBorderStyle.FixedDialog.

To enable or disable the minimize button, you can use

this.MinimizeBox = false;

How to Disable Maximize Button on Windows Forms using C#

Disable/Enable Maximize Box on Windows Forms


A Maximize button enables users to enlarge a window to full-screen size. To display a Maximize button, you must also set the form's FormBorderStyle property to FormBorderStyle.FixedSingle, FormBorderStyle.Sizable, FormBorderStyle.Fixed3D, or FormBorderStyle.FixedDialog.


A Maximize button automatically becomes a restore button when a window is maximized. Minimizing or restoring a window automatically changes the restore button back to a Maximize button.


To disable Maximize button


this.MaximizeBox = false;





Windows form Maximize Box

How to check if the OpenDialog is cancelled

How to check if the OpenDialog is cancelled

To check if the OpenDialog is cancelled try the following code

if (openXLFile.ShowDialog() == DialogResult.Cancel) {

MessageBox.Show("You have cancelled the dialog! Please select a file");

}

The CLR has been unable to transition from COM context 0x118b008 to COM context 0x118b178 for 60 seconds. The thread that owns the destination contex

ContextSwitchDeadlock was detected

Message: The CLR has been unable to transition from COM context 0x118b008 to COM context 0x118b178 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.

The contextSwitchDeadlock managed debugging assistant (MDA) is activated when a deadlock is detected during an attempted COM context transition.

Symptoms

The most common symptom is that a call on an unmanaged COM component from managed code does not return. Another symptom is memory usage increasing over time.

Cause

The most probable cause is that a single-threaded apartment (STA) thread is not pumping messages. The STA thread is either waiting without pumping messages or is performing lengthy operations and is not allowing the message queue to pump.

Memory usage increasing over time is caused by the finalizer thread attempting to call Release on an unmanaged COM component and that component is not returning. This prevents the finalizer from reclaiming other objects.

By default, the threading model for the main thread of Visual Basic console applications is STA. This MDA is activated if an STA thread uses COM interoperability either directly or indirectly through the common language runtime or a third-party control. To avoid activating this MDA in a Visual Basic console application, apply the MTAThreadAttribute attribute to the main method or modify the application to pump messages.

It is possible for this MDA to be falsely activated when all of the following conditions are met:

· An application creates COM components from STA threads either directly or indirectly through libraries.

· The application was stopped in the debugger and the user either continued the application or performed a step operation.

· Unmanaged debugging is not enabled.

To determine if the MDA is being falsely activated, disable all breakpoints, restart the application, and allow it to run without stopping. If the MDA is not activated, it is likely the initial activation was false. In this case, disable the MDA to avoid interference with the debugging session.

Resolution

Follow COM rules regarding STA message pumping.

To avoid these error popups from appearing, select Exceptions from the Debug menu from Visual Studio window and in the Exception Dialog box select the Managed Debugging Assistants Exception Node. Then select ContextSwitchDeadlock and remove the select from Thrown column




Warning: Variable 'XYZ' is used before it has been assigned a value. A null reference exception could result at runtime

Warning: Variable 'XYZ' is used before it has been assigned a value. A null reference exception could result at runtime

BC42104: Variable 'XYZ' is used before it has been assigned a value. A null reference exception could result at runtime

This error occurs when the variable is used before assigning a value. Most often it can be a part of some conditional statements

Dim sCurrentStage As String ' Holds the Current Process Name

Write2Log(sErrorText & " in " & sCurrentStage)

To avoid this warning assign a value in declaration

Dim sCurrentStage As String = "" ' Holds the Current Process Name

Friday, January 2, 2009

How to add XML Declaration to an XML document using C# (.NET)

Programmatically insert XML Declaration using C# (.NET)

The following snippet will be useful for inserting the XML Declaration for a given XML file.

private static void Add_Declaration_2_XML(String sXMLFile)

{

try

{

XmlDocument XDoc = new XmlDocument();

XDoc.Load( sXMLFile);

XmlDeclaration XDec;

XDec = XDoc.CreateXmlDeclaration("1.0", "us-ascii", "yes");

XmlElement XElem = XDoc.DocumentElement;

XDoc.InsertBefore(XDec, XElem);

XDoc.Save(sXMLFile + ".new");

}

catch (Exception ex)

{

Console.WriteLine(ex.Message);

}

}

XMLFile before Insertion

Newline Characters in C#

How to use New Line Characters in C#

NewLine characters can be used in variables in the form of escape sequences (\n for the NewLine character) as shown below

Console.WriteLine("Name:\tPraveen Dhaggay\nAge:\t34\nOccupation:\tConsultant");

The output will be:


How to Use Tabs in Variables in C#

C# use of Tab characters in variables

Tab characters can be used in variables in the form of escape sequences (\t for the tab character) as shown below

Console.WriteLine("Name\tAge");

The output will be:




Thursday, January 1, 2009

The Project Location is Not Trusted Dialog Box

This dialog box appears if you try to create a new client project or open an existing project on a Universal Naming Convention (UNC) path. By default, a UNC path is not a trusted location for a project. Your project might not run correctly when you try to debug or run from this location.

A local folder that is mapped to a network, such as the Documents and Settings folder, is not a trusted location. Therefore, solutions that are saved in mapped folders, which can include solutions that have been downloaded from the Internet, trigger this dialog box.




How to give file share FullTrust permission in .NET

To run Mscorcfg.msc from the Start menu

1. Click Start, click Control Panel, and then double-click Administrative Tools.

2. Double-click Microsoft .NET Framework Configuration.

To run Mscorcfg.msc from the command line

1. In the .NET Framework 1.0 and 1.1, type the following at the command line: %Systemroot%\Microsoft.NET\Framework\versionNumber\Mscorcfg.msc

2. In the .NET Framework 2.0, start the SDK Command Prompt and type mscorcfg.msc.

The user interface for the tool is displayed.

To run Mscorcfg.msc from the Microsoft Management Console

1. Start the Microsoft Management Console by typing the following at a command prompt: mmc.

2. On the File menu, click Add/Remove Snap-in (or press CTRL+M) to display the Add/Remove Snap-in dialog box.

3. In the Add/Remove Snap-in dialog box, click Add to display the Add Standalone Snap-in dialog box.

4. In the Add Standalone Snap-in dialog box, select a version of the .NET Framework Configuration tool, and then click Add.

One simple way to modify the policy affecting a file share is to give a specific file share FullTrust permission using Mscorcfg.msc. You must be an administrator on the computer to make this change.



To give a file share FullTrust permission

1. Start Mscorcfg.msc.




2. Expand the Runtime Security Policy node, the Machine node, the Code Groups node, and the All_Code node, and then highlight the LocalIntranet_Zone node.



3. In the right pane, click Add a Child Code Group.



4. Choose Create a new code group, enter a name for the code group, and then click Next.

5. Choose a condition type of URL, and enter the UNC path to the share location of your project, using the format file://\\servername\sharename\* where \\servername\sharename is the name of the share. Click Next.












To give a file share FullTrust permission

1. Start Mscorcfg.msc.

2. Expand the Runtime Security Policy node, the Machine node, the Code Groups node, and the All_Code node, and then highlight the LocalIntranet_Zone node.
3. In the right pane, click Add a Child Code Group.
4. Choose Create a new code group, enter a name for the code group, and then click Next.
5. Choose a condition type of URL, and enter the UNC path to the share location of your project, using the format file://\\servername\sharename\* where \\servername\sharename is the name of the share. Click Next.

Note:
Make sure to add the asterisk at the end of the path.
6. Choose Use existing permission set and select FullTrust, and then click Next.
7. Click Finish.
8. Restart Visual Studio.

Sleep Function in NET

Sleep Function in VB.NET

In Visual Basic 6.0, we used the Sleep API function to allow the process to ‘sleep’ for specified time interval. VB.NET comes up with an sleep function on its own

System.Threading.Thread.Sleep(500)

The argument 500 in the above code specified the number of milliseconds for which the thread is blocked.

Specify zero (0) to indicate that this thread should be suspended to allow other waiting threads to execute.

Specify Infinite to block the thread indefinitely.

Name 'XlFileFormat' is not declared.

Name 'XlFileFormat' is not declared.

PRefix the 'XlFileFormat' with Microsoft.Office.Interop.Excel

Imports Excel = Microsoft.Office.Interop.Excel

Excel.XlFileFormat.xlWorkbookNormal

Name 'XlCellType' is not declared Error in VB.NET

Name 'XlCellType' is not declared : PRefix the with Microsoft.Office.Interop.Excel

Imports Excel = Microsoft.Office.Interop.Excel

Excel.XlCellType.xlCellTypeLastCell

Sheets(1).cells.specialcells(Excel.XlCellType.xlCellTypeLastCell).row

kbAlertz.com :: Visual Studio 2005

kbAlertz.com :: Visual Studio 2008

kbAlertz.com :: Visual Basic 2005