Thursday, December 11, 2014

How can I make my window or control dock on my mainform just like Visual Studio IDE?

Introduction

How can I make my window or control dock on my mainform just like Visual Studio IDE?
Is there an easier way of making my application more friendly and more customizable?
Here is a component that may help you.

Background

I have been wondering for a long time: there are so many useful controls and components provided in Visual Studio, but why can't I find any docking control for my application?
I also used some third party or free controls for the same purpose, but most of them are not effective enough or they are powerful but do not have enough customization features.
On the other hand, I also want to challenge myself to see if I have the ability to create a tool that meets my own requirements.
Of course, the most important purpose is to provide a useful tool for every programmer who needs it.

Using the Code

The DockLayoutRanger is a WinForm component, and can be added and displayed into the Tool Box List of your Visual Studio IDE.
ToolBox
Then, use it like the other WinForm components, just drag it into your main form, and then theDockLayoutRanger will display as an icon like the image shown below:
Display Icon
If using this component in Visual Studio 2010 or above.
Make sure the [Target Framework] settings of your project can NOT be set to the
[.NET Framework 4 / 3.5 Client Profile] .
Target Framework Settings
Make sure a using statement has been added into your source code:
using System.Windows.Forms;
Now we done with all the prepared job.
Here, we can start creating some Control Panels:
public MainForm()
{
    InitializeComponent();
    
    //Create and setup all controls
    this.projectManagerToolStripMenuItem.Tag = new MyProjectManager("Project Manager");
    this.toolToolStripMenuItem.Tag = new MyToolBox("Tool Box");
    this.propertyWindowToolStripMenuItem.Tag = new MyPropertyView("Property Window");
    this.errorListToolStripMenuItem.Tag = new MyErrorList("Error List");
    this.outputToolStripMenuItem.Tag = new MyOutputBox("Output");
    this.commandToolStripMenuItem.Tag = new MyCommendBox("Command");
}
Start to dock these Control Panels in the location we want:
private void MainForm_Load(object sender, EventArgs e)
{
    //Docking control to the Left side
    this.dockLayoutRanger1.Dock(this, this.toolToolStripMenuItem.Tag as Control, 
    DockStyle.Left);

    //Docking control to the Right side 
    this.dockLayoutRanger1.Dock(this, this.projectManagerToolStripMenuItem.Tag as Control,
    DockStyle.Right);

    //Continue to dock control to the right side of the MainForm
    this.dockLayoutRanger1.Dock(this.propertyWindowToolStripMenuItem.Tag as Control);

    //Docking control to the Bottom
    this.dockLayoutRanger1.Dock(this, this.outputToolStripMenuItem.Tag as Control, 
    DockStyle.Bottom);

    //Continue to dock control to the bottom of the MainForm in Fill Mode
    this.dockLayoutRanger1.Dock(this.commandToolStripMenuItem.Tag as Control, 
    DockStyle.Fill, TabAlignment.Bottom);
}
"Dock" method is the main function that allows us to determine how to arrange our Controls:
 this.dockLayoutRanger1.Dock(
                this, //The container that will be docked
                this.toolToolStripMenuItem.Tag as Control, //The control that will dock 
        //into the container
                DockStyle.Left //How to dock
                );
Quote:
If you set the DockStyle argument to None, then the control will be directly show as a floating window.
Think of this like a sequential flow, if we want to dock a Control into the same side (LeftTopRightBottom) follow the earlier one, the component just needs to know which Control is to be docked instead of Containerand Dockstyle parameters transferring again:
 //Docking control to the Right side 
 this.dockLayoutRanger1.Dock(this, this.projectManagerToolStripMenuItem.Tag as Control, DockStyle.Right);

 //Continue to dock control to the right side of the MainForm
 this.dockLayoutRanger1.Dock(this.propertyWindowToolStripMenuItem.Tag as Control);
Similarly, if we want to dock a Control into the same location with the earlier one, and let the user switch between them by the tabs, we can set the Dockstyle argument to Fill and indicate the TabAlignment we want:
 //Docking control to the Bottom
 this.dockLayoutRanger1.Dock(this, this.outputToolStripMenuItem.Tag as Control, DockStyle.Bottom);

 //Continue to dock control to the bottom of the MainForm in Fill Mode
 this.dockLayoutRanger1.Dock(this.commandToolStripMenuItem.Tag as Control, 
 DockStyle.Fill, TabAlignment.Bottom);
Last, to make sure all of these Control Panels are visible or not when we check any of the corresponding Menuitems, add the statements below into the CheckedChanged event handle function:
  private void menuItem_CheckedChanged(object sender, EventArgs e)
  {
      Control control = (sender as ToolStripMenuItem).Tag as Control;
  
      if (control != null)
      {
          if((sender as ToolStripMenuItem).Checked)
              //Ensure control visible and make it center parent
              this.dockLayoutRanger1.Show(control, true);
              
              //Ensure control visible
              //this.dockLayoutRanger1.Show(control);
          else
              //Force hide control
              this.dockLayoutRanger1.Hide(control);
      }
  }
"Show/Hide" method will force display/hide any Control that has been docked by this component, no matter whether the specified Control has been closed or not and also regardless of whether it is docking into a form or floating like a window now.
Add code lines below to make sure Menu items can be responsive to the corresponding Controls visible status:
  private void viewToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
  {
      foreach (ToolStripItem item in (sender as ToolStripMenuItem).DropDownItems)
      {
          ToolStripMenuItem meniItem = item as ToolStripMenuItem;
  
          if (meniItem != null)
          {
              Control control = meniItem.Tag as Control;
  
              if (control != null)
              {
                  meniItem.CheckedChanged -= new EventHandler(menuItem_CheckedChanged);
  
                  meniItem.Checked = control.Visible && control.TopLevelControl != null;
  
                  meniItem.CheckedChanged += new EventHandler(menuItem_CheckedChanged);
              }
          }
      }
  }
After all of this hard work, now we can get to see a window by running the main program like this:
Default Style
(Of course, the MenuStripToolStripStatusBar and all Control Panels should have been prepared by other work before.)
This is the default style of the component present.
The DockLayoutRanger provides some of the properties that allow you to customize the form style for your own. You could browse all of these properties within the PropertyGrid of Visual Studio IDE:
PropertyGrid01 PropertyGrid 02
( Customizable Properties ) ( Image effect adjusting )
By specify these properties, you could customize many of the visual styles like the text font, backcolor, banner, button images, floating window style, and so on.
So, if you like, you could make your application form look like these:
XP Blue XP OlivXP Silver Win 8
Or these:
Leopard
Silver
Or whatever you want:
Pink
Hope this component will make your development work easier, more efficient and of course, happier.


original article in www.codeproject.com

Friday, July 11, 2014

How to send a Contact ID alarm to the Central Station from a C# application over VoIP

Background of the problem

Before describing the implementation of my solution, I am going to explain the most important terms you need to know for better understanding.
First of all, let’s take a look at the operation of the traditional alarm systems in a nutshell. You have an alarm system installed and configured in your office or home. This alarm system is connected to the Central Station. In case of emergency (e.g. fire, burglary, theft or any other intrusion) the alarm system sends an alert to the Central Station that will take the appropriate action to avert the emergency.
But using my solution, you (more specifically: your C# application) can behave as an alarm system. That is, you can send out any alarm in case of emergency to the Central Station. Let’s see a drastic example that illustrates how my application can improve your security system: Due to a protracted work, you are sitting in the office late night. Since you are in the building, the alarm system is not activated yet. But in the meantime you experience something unusual and there is a suspicion of emergency. In this case you can use this C# application in order to send out a Contact ID alarm to the Central Station. The following figure illustrates this process:
Figure 1: How to send a Contact ID alarm to the Central Station in C#
Mini glossary:
  • Alarm System: It is a system designed to detect intrusion (unauthorized entry), fire, gas leak, Carbon Monoxide leakage, high or low temperature, system trouble, communication trouble or any other emergency event.
  • Central Station: It refers to a company providing services to monitor burglar, fire and residental alarm systems.
  • Contact ID protocol: It is the most popular protocol that is used to establish communication between the alarm systems and the Central Station.

Implementation of the alarm sender application in C#

Getting started

Before starting the development, let's see what you need for this project. Considering that my application has been written in C#, you need a development environment that supports C# (such as Microsoft Visual Studio). Please do not forget to install .NET Framework on your PC as well. There is also a need for some VoIP components added to your references to be able to implement the VoIP functionality (such as Ozeki VoIP SIP SDK). Since I have used the Ozeki SDK for this project, you need to install this SDK on your PC, too.
  1. For creating a new Console Application, open your Visual Studio, click File > New project. Now select the Visual C# Console Application menu item and provide a name for your project. Finally click OK.
  2. For adding the VoIP components provided by the SDK, right-click on References and select the Add references menu item. Browse and select the VoIPSDK.dll file then click OK.

Code explanation

In order to make the communication possible between the alarm system and the Central Station I used the Contact ID protocol. The essence of the Contact ID procotol is that the receiver side sends a Handshake firstly. When the sender side receives that, it will start to send the message. That is both of the sides need to play the role of the sender and receiver as well. Therefore, in addition to the sender side, it is needed to talk a little about the receiver side as well. This is the reason why both of the sides has been built in one project.
Figure 2 illustrates the communication process using the Contact ID protocol:
Figure 2: The communication process using the Contact ID protocol
As you can see above, the alarm signal is a DTMF signal. However, the DTMF frequencies may be distorted during the communication with the Contact ID protocol, if you do not use a codec applying lossless compression. Therefore, you need to use PCMA or PCMU codecs.
In my project 2 classes have been used: Softphone.cs and Program.cs. Now it’s time to study the implementation of the two classes!

The implementation of the Softphone.cs class

First of all, you need to create a softphone (a software-based telephone that has the same features as an ordinary phone). It is required, because the transmission of the alarm will be carried out through a VoIP call. So the alarm sending will be managed with the help of this softphone. The Softphone.cs class is used to declare, define and initialize a softphone, how to handle the necessary events and how to use its functions. The Softphone.cs will be used to create a new softphone in the Program.cs class.
Code 1 shows that the first step is the addition of some using lines:
using System;
using Ozeki.Media;
using Ozeki.Media.MediaHandlers;
using Ozeki.VoIP;
using Ozeki.VoIP.SDK;
Code 1: Add some using lines
As you can see below, you need to create 3 objects (softphone, phone line and call) from the ISoftphone,IPhoneLine and IPhoneCall interfaces:
ISoftPhone softphone; // softphone object
IPhoneLine phoneLine; // phoneline object
IPhoneCall call; // call object
Code 2: Creating the softphone, phone line and call objects
You also need to initialize the softphone in the constructor using the default parameters. You need to set the port range indicated by the first parameter (minPortRange) and the second parameter (maxPortRange). This is called the port’s interval. It can be seen in Code 3 that it also contains a third parameter: this is the listening port. As you can see, this is 5060 that is the port of the SIP.
softphone = SoftPhoneFactory.CreateSoftPhone(5000, 10000, 5060);
Code 3: Initializing the softphone in the constructor
By subscribing to the IncomingCall event, incoming calls will be monitored continuously (Code 4).
softphone.IncomingCall += softphone_IncomingCall;
Code 4: Subscribing to the IncomingCall event
In order to be able to communicate, you need to register your softphone to a PBX by using the Register()method (Code 5). This method gets all of the values required for the registration as parameters that are used to create a SIP account with the constructor of the SIPAccount class:
  • RegistrationRequired: Is the registration required or not? To be able to receive incoming calls, this field needs to be set to ’true’.
  • DisplayName: A name to be displayed at the called client.
  • UserName: If an other client dials this name (number), this user is getting called.
  • AuthenticationId: An identifier (like a login name) to the PBX.
  • RegisterPassword: The password for registering to the PBX. It works in pair with the authentication ID.
  • DomainHost: A domain name, e.g. an IP address.
  • DomainPort: Port number.
After that the system will be able to create the phone line (CreatePhoneLine() method) by using the account. By subscribing to the PhoneLineStateChanged, you can track the changes of the phone line. When the phone line has been created, you need to register this phone line by calling the RegisterPhoneLine() method.
// Send SIP regitration request
        public void Register(bool registrationRequired, string displayName, string userName, string authenticationId, string registerPassword, string domainHost, int domainPort)
        {
            try
            {
                var account = new SIPAccount(registrationRequired, displayName, userName, authenticationId, registerPassword, domainHost, domainPort);
                Console.WriteLine("\n Creating SIP account {0}", account);

                phoneLine = softphone.CreatePhoneLine(account);
                Console.WriteLine("Phoneline created.");

                phoneLine.PhoneLineStateChanged += phoneLine_PhoneLineStateChanged;

                softphone.RegisterPhoneLine(phoneLine);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error during SIP registration" + ex.ToString());
            }
        }
Code 5: Subscribing to the IncomingCall event
You have already subscribed to get notified if the state of the phone line has been changed. With thephoneLine_PhoneLineStateChanged() method you can set what to do for each state. If the state of the phone line is RegistrationSucceeded, the system will examine whether the call has been started or not. You need to setup the numberToDial (a telephone number to be dialed) and the call object as well. As you can see below, you need to subscribe to the CallStateChanged by calling the call_CallStateChanged() method (Code 6).
void phoneLine_PhoneLineStateChanged(object sender, VoIPEventArgs<PhoneLineState> e)
        {
            Console.WriteLine("Phone line state changed to {0}", e.Item);

            if (e.Item == PhoneLineState.RegistrationSucceeded)
            {
                if (startCall)
                {
                    var numberToDial = "101";
                    call = softphone.CreateCallObject(phoneLine, numberToDial);

                    call.CallStateChanged += call_CallStateChanged;
                    call.Start();
                }
            }

            var handler = PhoneLineStateChanged;
            if (handler != null)
                handler(this, e.Item);
        }
Code 6: Managing the phone line states
If the CallStateChanged event occurs (that is the call state changes), the state of the call will be displayed.
  • If the call state is Answered, you need to create a PhoneCallAudioSender and aPhoneCallAudioReceiver in order to be able to send and receive audio during a call. In order to ensure that both of the sending and receiving works properly, the contactIdHandler object should be connected to the phoneCallAudioSender and phoneCallAudioReceiver objects when the call is established. It can be completed by using the mediaConnector. It ensures that both of the incoming and outgoing communication will be carried out through the contactIdHandler. After that, you need to run the contactIdHandler by calling the Start() method.
  • If the call state is Completed, you need to disconnect the established connections, and stop thecontactIdHandler by calling the Stop() method (Code 7).
        void call_CallStateChanged(object sender, VoIPEventArgs<CallState> e)
        {
            Console.WriteLine("call state changed: {0}", e.Item);

            if (e.Item == CallState.Answered)
            {
                phoneCallAudioSender = new PhoneCallAudioSender();
                phoneCallAudioReceiver = new PhoneCallAudioReceiver();

                // attach the phoneCallAudioSender and the phoneCallAudioReceiver to the call
                phoneCallAudioReceiver.AttachToCall(call);
                phoneCallAudioSender.AttachToCall(call);

                mediaConnector.Connect(contactIdHandler, phoneCallAudioSender); // connect the contactIdHandler to the phoneCallAudioSender object
                mediaConnector.Connect(phoneCallAudioReceiver, contactIdHandler); // connect the phoneCallAudioReceiver to the contactIdHandler object

                contactIdHandler.Start(); // start the contactIdHandler
            }
            else if (e.Item == CallState.Completed)
            {
                contactIdHandler.Stop(); // stop the contactIdHandler

                mediaConnector.Disconnect(contactIdHandler, phoneCallAudioSender);
                mediaConnector.Disconnect(phoneCallAudioReceiver, contactIdHandler);

                phoneCallAudioReceiver.Detach();
                phoneCallAudioSender.Detach();
            }
        }
Code 7: Managing the call states
The following method (Code 8) examines whether is there an incoming call or not. By calling thecall_CallStateChanged() method you can subscribe to the events of the CallStateChanged concerning to the incoming calls. The call will be equal to the current call and the call will be accepted automatically. To hang up an existing call use the HangUpCall() method.
void softphone_IncomingCall(object sender, VoIPEventArgs<IPhoneCall> e)
        {
            Console.WriteLine("Incoming call...");
            e.Item.CallStateChanged += call_CallStateChanged;
            call = e.Item;
            call.Accept();
        }
Code 8: Accepting an incoming call
To hang up an existing call use the HangUpCall() method (Code 9).
public void HangUpCall()
        {
            call.HangUp();
        }
Code 9: The HangUpCall() method

The implementation of the Program.cs class

First you need to add some lines in the ’using section’ (Code 10):
using System;
using Ozeki.Media.MediaHandlers;
Code 10: Add some extra using lines

Tuesday, June 3, 2014

Diving into OOP : All About C# Access Modifiers

Public, Private, Protected at Class Level

Whenever we create a class, we always want to have the scope to decide who can access certain members of the class. In other words, we would sometimes need to restrict access to the class members. The one thumb rule is that members of a class can freely access each other. A method in one class can always access another method of the same class without any restrictions. When we talk about the default behavior, the same class is allowed complete access but no else is provided access to the members of the class. The default access modifier isprivate for class members.
Point to remember: The default access modifier is private for class members.
Let’s do some hands on lab. Just open your Visual Studio and add a console application in C# namedAccessModifiers. You’ll get a Program.cs class file by default. In the same file, add a new class namedModifiers and add the following code to it:
using System;

namespace AccessModifiers
{
    class Modifiers
    {
        static void AAA()
        {
            Console.WriteLine("Modifiers AAA");
        }

        public static void BBB()
        {
            Console.WriteLine("Modifiers BBB");
            AAA();
        }
    }

     class Program
    {
        static void Main(string[] args)
        {
            Modifiers.BBB();
        }
    }
   }
So, your Program.cs file becomes like shown in the above code snippet. We added a class Modifiers and twostatic methods AAA and BBB. Method BBB is marked as public. We call the method BBB from Mainmethod.The method is called directly by the class name because it is marked static.
When we run the application, we get the output as follows:

Output

Modifiers BBB
Modifiers AAA
BBB is marked public and so anyone is allowed to call and run it. Method AAA is not marked with any access modifier which automatically makes it private, that is the default. The private modifier has no effect on members of the same class and so method BBB is allowed to call method AAA. Now this concept is called member access.
Modify the Program class and try to access AAA as:
class Program
    {
        static void Main(string[] args)
        {
            Modifiers.AAA();
            Console.ReadKey();
        }
    }

Output

'AccessModifiers.Modifiers.AAA()' is inaccessible due to its protection level
So , since method AAA is private, therefore no one else can have access to it except Modifiers class.
Note: Each and every code snippet written in this article is tried and tested.
Modifiers
Now mark the AAA method as protected, our class looks like:
class Modifiers
    {
        protected static void AAA()
        {
            Console.WriteLine("Modifiers AAA");
        }

        public static void BBB()
        {
            Console.WriteLine("Modifiers BBB");
            AAA();
        }
    }

Program

    class Program
    {
        static void Main(string[] args)
        {
            Modifiers.AAA();
            Console.ReadKey();
        }
    }

Output

'AccessModifiers.Modifiers.AAA()' is inaccessible due to its protection level
Again the same output. We cannot access the method AAA even after we introduced a new modifier namedprotected. But BBB can access AAA method because it lies in the same class.