Thursday, June 21, 2012

[ MFC ] - Custom CCommandLineInfo Example in VC++ to parse commandline Parameters


1. Introduction

We know that functions will sometimes take parameters and process it. Similarly, executable applications also take parameters and switches and it behaves based on the parameters passed to it. In this article, we will see how do we pass command line parameters to an MFC Dialog based applications. The approach is same for other applications like single document and multi-document applications.



2. Creating a dialog based application

First, create a dialog-based application and name it as CommandLineDlg. That is the name I had chosen but I am not restricting you keep the same name. Once the application is created, using the class view add a class to the solution. Name the class as CcommandParse.  Make this class derived from CCommandLineInfo. This class declaration is as follows:

class CCommandParse : public CCommandLineInfo



Creating the dialog based application is shown in the below video:

Video 1: Watch Here




3. The CCommandLineInfo Derived class

We have two MFC string Arrays declared in this class. One will hold command line data and another one will hold command line switches. Switches will tell how the application should behave and data is information passed for processing. The Get functions will receive reference parameters and copies the String Array values from class’s member variable.

The ParseParam function is overridden from the based class CCommandLineInfo. So in the implementation, we will get a chance to process each and every param passed from the command line.

Below is the Full Class definition:

class CCommandParse : public CCommandLineInfo
{
public:
  CCommandParse(void);
  virtual ~CCommandParse(void);

  //Sample 03: Get functions for params and switches
  void GetParams(CStringArray& params);
  void GetSwitches(CStringArray& switches);

private:
  //Sample 01: Private Members
  CStringArray m_params;
  CStringArray m_switches;

  //Sample 02: Override for Base class virtual
  void ParseParam(const TCHAR *pszParam, BOOL bFlag, BOOL bLast);
};

The ParseParam function will get called for each command line parameters (data and switches) and this function will store the command line arguments to m_params or m_switches flag, which is the second parameter to the function. Below is the overridden function:

class CCommandParse : public CCommandLineInfo
//Sample 04: Implement the Parse Param
void CCommandParse::ParseParam(const TCHAR *pszParam, BOOL bFlag, BOOL bLast)
{
             //Sample 04_1: Collect the parameters and switches in a separate Array
             CString param_or_switch(pszParam);
             if (bFlag)
                           m_switches.Add(param_or_switch);
             else
                           m_params.Add(param_or_switch);
}

AS already told the get functions will copy the command line arguments to the passed in reference String Arrays passed in. The code is straightforward and it is given below:

//Sample 05: Get Functions.
void CCommandParse::GetParams(CStringArray& params)
{
  int size = m_params.GetCount();
  for (int i = 0; i<size; i++)
     params.Add( m_params.GetAt(i));
}

void CCommandParse::GetSwitches(CStringArray& switches)
{
int size = m_switches.GetCount();
for (int i = 0; i<size; i++)
   switches.Add( m_switches.GetAt(i));
}

That all the changes we need for the CcommandParse class. Now we will move to the Application Instance and make the necessary changes. That is we are going to use the class that we defined just now.



4. Application Instance Parsing Params & Switches

In the application class, we included our custom parser, which we discussed in the previous section. Then the function GetCommandLinePasrser is declared to receive the command line parameters by passing the references to the CStringArray instances. Finally, we declared our custom parser as the member variable. The entire header file is shown below:

//Sample 06: Include the Custom Parse
#include "CommandParse.h"
// CCmdLineDlgApp:
// See CmdLineDlg.cpp for the implementation of this class
//
class CCmdLineDlgApp : public CWinApp
{
   public:
   CCmdLineDlgApp();

   // Overrides
   public:
   virtual BOOL InitInstance();
   //Sample 07: Fill the passed in array structures.
   void GetCommandLinePasrser(CStringArray& params, CStringArray& switches);
  //Sample 08: To pasrse command line arguments
   private:
   CCommandParse m_cmdParse;
  // Implementation
   DECLARE_MESSAGE_MAP()
};

The InitInstance function of the application class gets called when the application is initialized. In this function, we passed our custom command line parser object to the function call ParseCommandLine. Now the MFC API is aware of the extended functionality of the default command line parsing. For each command line arguments passed, MFC will now call our overridden ParseParam member function CcommandParse that we derived from the class CCommandLineInfo. Below is the piece of code:

//Sample 09: Use the Custom Command Line Parser
ParseCommandLine(m_cmdParse);
if (ProcessShellCommand(m_cmdParse))
 return FALSE;

The Application instance will make a call to the custom command line instance m_cmdParse to get the Command params and switches. The dialog class calls this member function. Below is the piece of code:

//Sample 10: The command Line parser will do the copy
void CCmdLineDlgApp::GetCommandLinePasrser(CStringArray& params, CStringArray& switches)
{
 m_cmdParse.GetParams(params);
 m_cmdParse.GetSwitches(switches);
}


5. The Dialog class

In the dialog, we just have two list boxes. The dialog template edited by IDE is shown below:



The above-displayed dialog will get the application instance and pass two string arrays by reference to the member exposed by the application instance. The application instance will make a call to the custom command line parser to get the parameters and switches. Once the dialog knows the parameters and switches, it will display it in the corresponding list boxes.

All the above said stuff is done in the InitInstance member function of the dialog. Look at the below piece of code:

//Sample 11: Add the Command Line Arguments to List controls.
CStringArray params, switches;
 ((CCmdLineDlgApp *) AfxGetApp())->GetCommandLinePasrser(params, switches);
 for (int i = 0; i<params.GetCount(); i++)
              m_lst_params.AddString(params.GetAt(i));
 for (int i = 0; i<switches.GetCount(); i++)
              m_lst_switches.AddString(switches.GetAt(i));

First, we collected the params and switches in the CString array instances by calling the application instance’s member function GetCommandLinePasrser. Once the dialog has the information, it displays it by adding it to the corresponding m_lst_params, m_lst_switches by iterating through the CStringArray instances.



6. Testing the sample

The attached sample can be tested in two different ways. The first way is going to the command prompt and executing the exe by passing the command line argument. The second way is passing the static parameters by setting the debug property of the project. The second method is useful when we want to debug the sample.

Below video shows passing the command line argument (with switches) from the command prompt.

Video 2: Watch Here


Below video shows perform debugging with command line arguments.

Video 3: Watch Here



Source Code: Download

Sunday, June 17, 2012

C# - Playing sound using System.Media and Windows Media Player Control

1. Introduction

We will see how we can play sound files in C#. Sound can be played in two different ways. One way of playing is using the "System.Media Namespace" and the other way is using the "Windows Media Player Active-X Control".

In this article, I will cover both the methods by playing a ".wav file". You can explore yourself for more functionality on the specific area. OK, Let us start.

2. About the Sample

The sample application’s screenshot is shown below:



The Play button will start playing the sound and stop button will stop it. Loop It checkbox will be enabled when you click the stop button and it is disabled when the sound is playing. When the check box is in the checked state the sound file will be played repeatedly. Next portion of the form is occupied by the Windows Media Player ActiveX control which plays the same sound file played by the sound player.


3. Adding sound as Resource

In the first method, we are going to use the sound as an application resource. So first we added the sound file to our project and then it is drag and dropped to the resource collection. This whole step is shown in the below video.



Video Steps


  1. Create a folder for sound
  2. Add a single sound wav file to the sound folder in project explorer
  3. Drag and Drop this added sound file to the application’s resource collection.

4. Source Code for using SoundPlayer

1) Before the form class definitions, use the required namespace for playing the sound. In the first method, we are going to access the SoundPlayer class to play the sound. Below is namespace inclusion:

//Sample 01: Include the Required Namespace
using System.Media;

2) Next, a private member of type SoundPlayer is created. We will use this instance player for playing the sound. Below is the code:

//Sample 02: Create Sound Player
private SoundPlayer player = new SoundPlayer();

3) When the play button is clicked first we should disable the check box. Then we will play the sound that we added as the sound resource. While playing sound we check the status of the checkbox and based on the status we play the sound once or repeated. Below is the code for that:

//Sample 03: Play button handler
private void btnPlay_Click(object sender, EventArgs e)
{
    //Sample 03_1: Disable the Checkbox button
    chkLoop.Enabled = false;

    //Sample 03_2: Play the wav or do play looping
    player.Stream = Properties.Resources.song1;

    if (chkLoop.Checked)
    {
        player.PlayLooping();
    }
    else
    {
        player.Play();
    }
}

In the above code, we accessed the sound using the "Properties.Resources" and the sound resource is assigned to the "Stream Property" of the player object. The "Play() Method" will play the sound once and "PlayLooping() Method" will play the sound file multiple times.

The IntelliSense feature will help you add the resource added to the resource collection. We added song1.wav as a sound resource and in the below video you can see accessing the added resource in code with IntelliSense help.



Video Steps


  1. Move to the Tag sample 3_2 in the code window
  2. Shows IntelliSense help for the added sound resource

4) When the stop button is clicked we call Stop method of the player and in the meantime enable the check box so that play mode can be changed. Below is code for the stop method:

//Sample 04: Stop the Sound Player
private void btnStop_Click(object sender, EventArgs e)
{
    player.Stop();
    chkLoop.Enabled = true;
}

Note that the above method that is using the SoundPlayer class method will support only wav files. To play other sounds or even videos we should use the "Windows Media Player Control".

5. The Windows Media Player Control

Windows Media Player control is not a standard control. This is available as an active-x control and it will be available when you installed Windows Media Player in your system. This control supports rich functions, but for this sample, I just gave the simple function of playing the sound file.

Look at the below video that shows how the window media player control is added to the form.



Video Steps


  1. From the toolbox general area, choose items option is selected using the context menu.
  2. In the displayed dialog, COM components tab opened
  3. Window media player control is selected from the bottom of the list
  4. The Component added to the toolbox is placed on the form for use

After placing the control its default name is changed to WMPlay. In the form load the below piece of code is added:

//Sample 05: Set Sound URL for the Media Player
private void frmSound_Load(object sender, EventArgs e)
{
    string URL = "song1.wav";
    WMPlay.settings.autoStart = false;
    WMPlay.URL = URL;
}

In the form load, the "autoStart Property" of the control is set to false. That means, even though the control is aware of what it needs to play, it will wait for the user to say “OK, Now you play the loaded file”. In the form load after turning off the Auto Start, we specified the URL, which is nothing but the path to the sound file. Here in the above, I don’t specify any path so it will assume that the file will be available in the same location where the exe is placed.

When the form is displayed, the media player is ready to play the loaded sound file. All it need is somebody pressing the play button on it and once it is pressed media player start playing the sound.

The Window media player active-x control is a rich control and you can play different types of sound as well as a video file.


Source Code : Download

Saturday, June 02, 2012

ASP.Net - Understanding and Using Web.Config and ASP.Net Configuration Tool


1. Introduction

Web configuration files are important for all the ASP.net hosted websites. Every application requires some kind of settings that tells the application how should it behave. Also, it comes handy when we use as all the settings go in one place and if somebody wants to change some settings they know this one stop place. What if we don’t use these configuration files? Well. You should do it through the code. Imagine the situation of 100 settings, if it is done in the code and anyone out of that 100 requires configuration change, first somebody need to search and pin point the piece of code that requires the changes, then they should build (Web Site Down) and re-launch the websites (Web Site Up). Configuration files avoid rebuilding the websites assemblies.



2. Machine Level Configuration

Dot.Net supplies some default configuration for the essential configuration that is actually required by the application. Where from these settings coming from? Say for example even when I don’t specify a connection string the default is set to SQL Server of the local machine. Who is supplying that? Web.Config file is the answer if the connection string is specified there. What If it is not there? OK, the dot Net framework supplies two parent configuration files and some machine level general settings can be specified there. Our application actually overrides those defaults when required.

The below picture shows the default configuration files:



The screen shot shows two different configuration files. One is Machine.config and the other one is web.config. They both act as a parent for other application specific configuration files. Also, note the path. The path tells you that these common configuration files are for Dot Net Framework version 2.0 (One that come with Vs2005 IDE). You will have the same set of configuration files for other versions of the framework also.

OK. Why two different files here? The Web.Config file is for all the Web applications and machine.config file is for all the dot net applications machine wide. So if my application is not a web application, only machine.config file comes into the picture. In the mean time, if my application is web based, both machine.config and web.config comes into the picture. Modifying these files requires administrator privilege.



3. Multiple Config files & Order

Most of the web project will be organised in different folders. We can visualise that like root folder and sub-folders. And each sub-folder may have their web.config file and this is how we will come across multiple web configuration files. Consider the below-shown picture:



The C-SharpCorner.com is the root folder and it has two sub-folders namely DBCorner and VBCorner. Now the site has three homes and those can be accessed like:


The Links won’t work except first one, as this is just an example for explanation purpose. Assume that each link displays their own home page and has three different settings. So we need the web pages from three different groups and these groups have independent settings. That why we have three different web.config files on each folder.

Let us say a page inside the VBCorner sub-folder is loading. Now the configuration settings are read by the page in the below-specified order:
1) Machine.config file from the window\DotNetFramework Folder (See Picture 
2) Web.Config from the same folder (Only for the web application)
3) Web.Config from the D:\C-AskCorner.com folder
4) Web.config from the DbCorner folder
5) Web.Config from the VBCorner folder

Note that the Latest setting which is available in the vbcorner web.config file be in effect when the same setting is specified in all the configuration files. Also, be aware that the parent should say it is Okay to override my settings.



4. About the Example

The sample is Simple Link pages. The main page has 4 hyperlinks and last one among them is intentionally broken. First, we will look at the usage of the configuration file and then walk through learning how do we turn on the tracing and debugging. Finally, we will see how do we set the default error page. The default error page is one, which is displayed when ASP.Net throws an error page. Below screen shot shows the link page:



When the Last broken link is clicked, the below-shown system error page is displayed. We are going to replace that error page with our custom error page.





5. Preparing the Example

Creating the sample is simple as it has only 4 link buttons. In this, we had first three hyperlinks has valid linked pages and last one refers a page that is not part of the project (Intentionally Broken) to demonstrate the usage of Default Error Page. Below video shows defining the Error Page.

Video Steps:

1) A Web Form (ErrorPage) is added to the Project
2) Then A Label is placed in the Web Form
3) Error text is typed in the label and some properties are set for the label.



And next video here shows setting the properties for the HyperLink control.

Video Steps:

1) Selects already placed hyperlink control and invokes properties for it
2) Along with other properties sets the hyperlink property



6. Enable Debugging

By default the debugging feature is disabled in ASP.net. When you press F5/Chose Start Debugging from debug menu, a dialog as shown below appears:



When you click ok to this dialog, the debugging feature is enabled for the solution. It makes an entry in the web.config file mentioning that web application can allow debugging. Web.Config is shown below (Portion of it):



When we deploy the website we should make sure that the debugging feature is turned off. Because this will slow down the performance of the website and this is why the debugging is turned off by default. Below video shows turning on debugging web application:

Video Steps:

1.     Start Debugging is clicked from the debug menu
2.     Debug produces not enabled dialog displayed and asking for confirmation to turn it on. Clicked on the dialog
3.     In the web, configuration debug switch is set to true





7. Turn-on Tracing

Just like debugging we cab turn on the tracing also. Tracing is a process, which will log the useful information and displays it when required as the information is persisted. This is useful for getting quick information without debugging the application. We can turn on the tracing feature using the ASP.Net Configuration tool.


The below picture shows how do we turn on this feature. Highlighted ones are the setting we changed from its default. We configured to Capture 15 trace requests on individual pages.




The tracing information configured by the tool is also viewable in the web.config file. The tracing turned on by the tool is shown below:





The videos given below shows how do we turn ON the trace feature and Capture Trace information:

Video Steps:

1) Invokes ASP.Net Configuration utility from the explorer menu
2) From the Application tab, under the debugging and tracing, Configure Debugging and Tracing link are clicked
3) From the displayed page the tracing requirements are set



Video Steps:

1) Opens the home page (The Page with all 4 links)
2) From the context menu, the page was browsed through Internet explorer
3) The captured trace information is shown





8. Defining Custom Error Page

Custom Error page is used to redirect the user to show error message defined by us. The system error message is not useful for the end users browsing the page and in such situations we display our own pages. In the attached sample solution clicking the Link Broken link as shown below generates the systems error. The system generated error information also shown in the below screenshot.

Broken link on the Home Page



System supplied Error Message



We can use the ASP.Net Configuration utility to define the default custom error pages. Once it is specified, we do have an entry for the custom error page in the web configuration file and the entry says which page to navigate when an error occurs.

Below specified videos show how do we configure the default error page and generates an error to show the re-directed page.

Video Steps

1) Navigate to the ASP.Net Configuration utility
2) From the displayed tool, application tab is selected
3) Then from the displayed page, define default Error page link is clicked
4) From the displayed page, default error page is defined
5) The custom error page entry is shown in the config file.
6) Finally, the mode attribute is turned on by editing (The tool turned it off by default) the web.config file.



Video Steps:

1) Using the Google Chrome web browser, the home page is viewed from the solution explorer
2) From the displayed home page the broken web link is clicked
3) In place of showing the system error message (One shown above picture) we see a default error page



Source Code: Download

Like this site? Tell it to your Firend :)