Archive

Posts Tagged ‘Windows Forms’

Create UAC Compatible applications in .NET

September 1st, 2010 Anuraj P No comments

In my last project I got an opportunity to make my application compatible with Windows Vista and Windows 7. The main issue I faced was UAC; User Account Control (UAC) which introduced with the launch of Windows Vista; this provides users a better and safer computing experience. If UAC enabled, Windows will prompt every time when Applications try to access File System, like writing / creating Files in Program Files Folder, Windows Folder etc. (It’s not a best practice to write / create files in System directories like Windows, Program Files etc.). It’s also not a best practice to ask the customer to disable the UAC and run the application. The alternate is to make the application compatible with UAC, so that when the customer runs the application the system will prompts the UAC dialog, and run the application with Administrator privileges.
The procedure to make the application compatible with UAC is simple.

  1. Right-click project and add a new item.
  2. From the Add New Item box select Application Manifest File.
  3. In the manifest file un-comment the following line:
    <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
    

Build your application. And when the build is complete you will see the security shield icon accompanying your application icon.

Security shield icon accompanying application icon

Security shield icon accompanying application icon

A dialogue box appears in front of the user to run the application with full administrative privileges.

UAC Dialog box when double clicking on the Application

UAC Dialog box when double clicking on the Application

How to disable Close button of Windows Forms Application

August 25th, 2010 Anuraj P No comments

We can disable the close button of a Windows Form in three ways

  1. Set controlbox property to false – It is most easy way to do this. But it also hides the Minimize and Maximize buttons.
  2. Using WIN32 API – Using Win32 API, we are getting the system menu and removes the close menu item using Remove menu item.
    Here is the Code.

    const int MF_BYPOSITION = 0x400;
    [DllImport("User32")]
    private static extern int RemoveMenu(IntPtr hMenu, int nPosition, int wFlags);
    [DllImport("User32")]
    private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
    [DllImport("User32")]
    private static extern int GetMenuItemCount(IntPtr hWnd);
    
    //In the Form load event
    IntPtr hMenu = GetSystemMenu(this.Handle, false);
    int menuItemCount = GetMenuItemCount(hMenu);
    RemoveMenu(hMenu, menuItemCount - 1, MF_BYPOSITION);
    

    And here is the screenshot

    Using WIN32 API

    Using WIN32 API

  3. By Overriding the CreateParams property – The CreateParams property gets the required creation parameters when the control handle is created. By overriding the property we are removing the close button. You can get more information about CreateParams in MSDN
    Here is the code.

    private const int CS_CLOSE = 0x200;
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams parms = base.CreateParams;
            parms.ClassStyle |= CS_CLOSE;  //
            return parms;
        }
    }
    

    And here is the screenshot

    By Overriding CreateParams property

    By Overriding CreateParams property

    All of above three methods will work fine. But if you are using Windows 7 none of the above will work or OS will override all these.

    Windows 7 - Close Window

    Windows 7 - Close Window

Creating Wizard using Windows Forms

August 9th, 2010 Anuraj P No comments

In my first WinForms application, I have to create various wizard screens, I couldn’t find any ready made Controls for it from Microsoft. Then one of my colleague suggested a way to tweak it, like Add a Tab Control, Set the Alignment property to bottom and add a panel on top of the Tab Control, which contains Next / Previous / Cancel buttons. It was working fine. Few days back again I got the same situation for one of my personal project, and I thought about writing a control for the same. After doing some research I found a simple code snippet, which helps to hide the Tab Pages title in Runtime.

Here is the code, in this I am extending the Tab control and overriding the WndProc event.

protected override void WndProc(ref Message m)
{
    // Hide tabs by trapping the TCM_ADJUSTRECT message
    if (m.Msg == 0x1328 && !DesignMode)
    {
        m.Result = (IntPtr)1;
    }
    else
    {
        base.WndProc(ref m);
    }
}

You can find more details about TCM_ADJUSTRECT Message on MSDN.

Selecting controls using LINQ

July 19th, 2010 Anuraj P No comments

One of my colleague asked how to get all the text boxes with no text entered in Windows form without using a For Loop. I thought of writing it with LINQ. And here is my implementation.

 var controls = from control in this.Controls
                           select control;

But this will generate a compile time error – Could not find an implementation of the query pattern for source type ‘System.Windows.Forms.Control.ControlCollection’. ‘Select’ not found. Consider explicitly specifying the type of the range variable ‘control’. But the error was self explanatory, I need to specify the type of the control. And here is the modified version.

var controls = from Control control in this.Controls
                           select control;

And if you want to select specific type of controls you need to apply a where condition.

var textboxes = from Control textbox in this.Controls
                where textbox is TextBox
                select textbox;

There is some other inbuilt operators is also available to select specific controls, like OfType()

var textboxes = from textbox in this.Controls.OfType<TextBox>()
                select textbox;

In this method we don’t need to specify the type of the control in the from statement. And one of interesting LINQ extension method is the Cast<> method, which helps to enable the standard query operators to be invoked on non-generic collections by supplying the necessary type information. You can get more information from here.

Implementing Print using C#

July 8th, 2010 Anuraj P No comments

The first assignment I got from my lead in my previous company was to create Print option to the accounting package we were working. The application was developed in VB 6.0. And we were used batch files and command prompt for printing accounting related documents from the application. Few days back one of colleague asked how we can print from C#, he was developing an accounting package for his uncle. I said something like we need to use PrintDocument class for that, but I couldn’t give him a sample code. Today I got some free time in Office so I thought about implementing printing from C#. Here is a simple implementation, which displays a Print Dialog, and based on the settings, it will print the contents of the textbox.

I tried to print the document based on the ForeColor of the TextBox, but it was throwing some error, I couldn’t resolve itIts fixed. :) Source code is pretty self-explanatory. Happy Printing.

private int startIndex = 0;
private void printToolStripMenuItem_Click(object sender, EventArgs e)
{
    PrintDocument printDocument = new PrintDocument();
    //Print Options dialog.
    using (PrintDialog printDialog = new PrintDialog())
    {
        printDialog.ShowHelp = false;
        printDialog.ShowNetwork = false;
        printDialog.Document = printDocument;
        printDialog.AllowPrintToFile = true;
        //As its a simple text file, disabling the advanced options.
        printDialog.AllowCurrentPage = false;
        printDialog.AllowSelection = false;
        printDialog.AllowSomePages = false;
        //Display XP Style Print Dialog
        printDialog.UseEXDialog = true;
        if (printDialog.ShowDialog(this) == DialogResult.OK)
        {
            //Assigning the Printer settings to the Document.
            printDocument.PrinterSettings = printDialog.PrinterSettings;
            printDocument.PrintPage += new PrintPageEventHandler(printDocument_PrintPage);
            //Number of copies
            for (int i = 0; i < printDialog.PrinterSettings.Copies; i++)
            {
                startIndex = 0;
                //Print method call.
                printDocument.Print();
            }
        }
    }
}

And here is the Print Page event.

protected void printDocument_PrintPage(object sender, PrintPageEventArgs e)
{
    //Setting the color as Black.
    Brush brush = Brushes.Black;
    //Setting color dynamically
    //Brush brush = new SolidBrush(this.txtEditor.ForeColor);
    int lineCounter = 0;
    float lineTop = 0;
    //Looping throught each line in the textbox.
    for (int lineIndex = startIndex; lineIndex < this.txtEditor.Lines.Length; lineIndex++)
    {
        string line = this.txtEditor.Lines[lineIndex];
        lineCounter++;
        //Writing the line to the document.
        lineTop = e.MarginBounds.Top + lineCounter * this.txtEditor.Font.Size;
        e.Graphics.DrawString(line,
            this.txtEditor.Font,
            brush,
            e.MarginBounds.Left,
            lineTop);
        //Checking for more pages.
        if (lineTop > e.MarginBounds.Bottom)
        {
            startIndex = lineIndex;
            e.HasMorePages = true;
            return;
        }
    }
}

Custom Places in FileDialog box

June 21st, 2010 Anuraj P No comments

If you ever tried to Open a File from Visual Studio, you may notice something like Projects Folder in the Open File Dialog.

Open File Dialog in Visual Studio

Open File Dialog in Visual Studio

We can also implement the same functionality in our applications by using CustomPlaces collection property of FileDialog class. The OpenFileDialog and SaveFileDialog classes allow you to add folders to the CustomPlaces collection.

openFileDialog.CustomPlaces.Add(@"C:\Users");

You can also specify GUID of Windows Vista known folder. Known Folder GUIDs are not case sensitive and are defined in the KnownFolders.h file in the Windows SDK. If the specified Known Folder is not present on the computer that is running the application, the Known Folder is not shown.

openFileDialog.CustomPlaces.Add(@"C:\Users");
//Desktop Folder
openFileDialog.CustomPlaces.Add(new Guid("B4BFCC3A-DB2C-424C-B029-7FE99A87C641"));
//Downloads Folder
openFileDialog.CustomPlaces.Add(new Guid("374DE290-123F-4565-9164-39C4925E467B"));
Open File Dialog with Custom Places

Open File Dialog with Custom Places

Note: This feature will not have any effect in Windows XP. Also you must set the AutoUpgradeEnabled to True(default) to enable this feature in Vista or Windows 7.

The following table lists few Windows Vista Known Folders and their associated Guid.

  1. Contacts : 56784854-C6CB-462B-8169-88E350ACB882
  2. ControlPanel : 82A74AEB-AEB4-465C-A014-D097EE346D63
  3. Desktop : B4BFCC3A-DB2C-424C-B029-7FE99A87C641
  4. Documents : FDD39AD0-238F-46AF-ADB4-6C85480369C7
  5. Downloads : 374DE290-123F-4565-9164-39C4925E467B
  6. Favorites : 1777F761-68AD-4D8A-87BD-30B759FA33DD
  7. Fonts : FD228CB7-AE11-4AE3-864C-16F3910AB8FE
  8. Music : 4BD8D571-6D19-48D3-BE97-422220080E43