Walkthrough: Creating a Rich Client Application with MFC

The following walkthrough describes one procedure for creating an MFC-based rich client application and various other features of Visual Studio .NET.

During the course of this walkthrough, you will accomplish the following activities:

  • Design an MFC-based solution that displays data from an existing database and displays the following features using several dialog boxes:

    • Hosting a windowless ActiveX control

    • Using dynamic HTML (DHTML) dialog boxes

    • Validating the application user using an existing XML Web service.

To complete the walkthrough, you must provide an existing database and at least one searchable table.

Note

This walkthrough uses the pubs database and authors table as an example database and table.

Creating the MFC Rich Client Application

To create the MFC application

  1. On the File menu, click New, and then click Project.

    The New Project dialog box appears.

  2. In the Project Types pane, click Visual C++ Projects, and in the Templates pane, click the MFC Application icon.

  3. In the Name box, enter MyProject.

  4. Click OK to close the dialog box and open the MFC Application Wizard.

Using the MFC Application Wizard, you will modify your project to support the database access and display features of the rich client application.

Note

This walkthrough assumes that the server being accessed is a SQL server and that the pubs database exists on this server.

To implement database support

  1. In the MFC Application Wizard, select Database Support.

  2. Select the Database View with File Support option.

  3. Click the Data Source button.

  4. From the OLE DB Provider(s) list box, click the Microsoft OLE DB Provider for SQL Server item and click Next.

  5. Enter or select an existing server name.

  6. Select Use Windows NT Integrated Security.

  7. Select the pubs database.

  8. Click the OK button to establish the connection.

  9. In the Select Database Object dialog box, select the authors table.

  10. Select OK to close the dialog box.

  11. Click Finish to create the framework application.

  12. After you create the project, you will need to remove the #error line from MyProjectSet.h.

Once the framework application is created, major features can be added.

Accessing and Displaying Data from an Existing Database

In this section, you will use a simple form and control to demonstrate the access and display of data from the authors table. Because this is only a demonstration, the query and display are simple. The results of the query (all authors in the table) are displayed in a list box.

The MyProject application already contains a form object (called IDD_MYPROJECT_FORM), located under the Dialog node in Resource View. You will modify this form to display a simple list of authors from the authors table.

To modify the form

  1. In Resource View, expand your project, expand the Dialog node, and double-click the default form object (IDD_MYPROJECT_FORM).

  2. Drag a List Box control onto the default form.

  3. Right-click the List Box control and, on the shortcut menu, click Add Variable.

    The Add Member Variable Wizard appears.

  4. In the Variable name box, enter m_DataList and click Finish.

  5. Drag a Button control onto the default form. In the Properties window, change the Caption box to Control Host.

  6. Drag a Button control onto the default form. In the Properties window, change the Caption box to DHTML Dialog.

    Note

    These two controls will be used later in the walkthrough to access other features of the application.

To display the query results

  1. In Class View, expand the project node and double-click the OnInitialUpdate method of the CMyProjectView class.

  2. Add the following code after any existing code in the function:

       HRESULT hr = S_OK;
       TCHAR szAuthor[80];
    
       CMyProjectSet &dbset = GetDocument()->m_MyProjectSet;
       [db_command(command= "SELECT au_lname" \
                            "([bindto]szAuthor)" \
                            "FROM AUTHORS",
                   name="cmd",
                   source_name="dbset",
                   hresult="hr")];
       while(cmd.MoveNext() == S_OK)
          m_DataList.InsertString(-1, szAuthor);
    

    This code uses the db_command attribute to initialize the data set of the document object (m_MyProjectSet) with the last names of all current authors in the table.

  3. On the Build menu, click Build Solution.

  4. On the Debug menu, click Start Without Debugging.

    The results of the query will be displayed in the list box of the child view form.

Creating and Hosting a Windowless ActiveX Control

The next modification to the rich client application is a dialog box that hosts a simple windowless custom control. The first step is to create a custom ActiveX control with a simple event. Then a dialog box object is created containing the control and handling the control event.

To create the custom control

  1. In Solution Explorer, right-click the MyProject solution.

  2. On the shortcut menu, click Add, and then click New Project.

    The New Project dialog box appears.

  3. In the Project Types pane, select Visual C++ Projects, and in the Templates pane, click the ATL Project icon.

  4. Enter CustomCtl for the name of the new project and click OK.

    The ATL Project Wizard appears.

  5. Click Finish to accept the default settings and create the project.

  6. Right-click the CustomCtl project.

  7. On the shortcut menu, click Add, and then click Add Class.

    The Add Class dialog box appears.

  8. Double-click the ATL Control item.

    The ATL Control Wizard appears.

  9. In the ATL Control Wizard, enter MyCtl in the Short name box.

  10. On the Options page, choose Connection points.

  11. Click Finish to create the custom control object.

Once the control is created, you will add a simple event called Click. This event is fired by the control whenever the mouse is clicked within the control area.

To create the Click event

  1. In Class View, expand the CustomCtl node.

  2. Right-click the event interface for the custom control (_IMyCtlEvents).

  3. On the shortcut menu, click Add, and then click Add Method.

  4. Enter the following values using the Add Method Wizard:

    • Return type: void

    • Method name: Click

  5. Click Finish to create the Click event.

  6. In Class View, select the control class (CMyCtl).

  7. In the Properties window, click the Messages button and add an OnLButtonDown handler for the WM_LBUTTONDOWN message.

  8. Add the following code to the handler body:

       Click();
       return 0;
    
  9. On the Build menu, click Build Solution.

Once the solution builds successfully, a simple dialog box can host the control.

To host the control

  1. In Resource View, right-click the MyProject solution.

  2. On the shortcut menu, click Add, and then click Add Resource.

  3. Click the Dialog item and click New.

  4. Right-click the IDD_DIALOG1 dialog box and click Add Class on the shortcut menu.

    The MFC Class Wizard appears.

  5. In the MFC Class Wizard, enter the following values:

    • Class name: CMyCtlDlg

    • Base class: CDialog

  6. Click Finish.

  7. Right-click the IDD_DIALOG1 dialog box and select Insert ActiveX Control on the shortcut menu.

  8. In the Insert ActiveX Control dialog box, select MyCtl Object and click OK to add the control.

  9. Select the ActiveX control on the dialog template.

  10. From the Properties window, click the Control Events button and add a ClickMyctl1 handler for the Click event.

  11. Add the following code to the body of the event handler:

       AfxMessageBox("Click event fired");
    

The final step involves hooking the dialog box to the rich client application. This is accomplished with code in the handler for the Control Host button you created earlier, in the topic Accessing and Displaying Data from an Existing Database.

To display the control host dialog box

  1. In Resource View, display the main form by double-clicking the IDD_MYPROJECT_FORM (located under the Dialog node of the resource file for the MyProject solution).

  2. Double-click the Control Host button, added earlier.

  3. Add the following code to the handler function:

       CMyCtlDlg dlg;
       dlg.DoModal( );
    
  4. Add the following code after the last #include statement in the current source file:

    #include "MyCtlDlg.h"
    

    This includes the .h file of the class implementing the control host dialog box.

  5. On the Build menu, click Build Solution.

  6. On the Debug menu, click Start Without Debugging.

You can invoke the control host dialog box by pressing the Control Host button. Fire the custom Click event by clicking the left mouse button within the control.

Implementing a DHTML Dialog Box

Another feature of rich client applications is the usage of dialog boxes that use HTML for the user interface rather than traditional dialog resources. For the purposes of this walkthrough, a simple DHTML dialog box will be implemented, containing an image control that displays a simple bitmap.

To implement the DHTML dialog box

  1. In Resource View, right-click the MyProject project.

  2. On the shortcut menu, click Add, and then click Add Resource.

  3. Click the Dialog item and click New to create a new dialog box.

  4. Remove the OK and Cancel buttons from the dialog template; these are implemented in HTML in subsequent steps.

  5. Right-click the IDD_DIALOG2 dialog box form and select Add Class.

  6. Enter the following values:

    • Class name: CMyDhtmlDlg

    • Base class: CDHtmlDialog

  7. Click Finish.

  8. In Resource View, under the HTML node, double-click the IDR_HTML_MYDHTMLDLG item and click the HTML tab under the design pane to edit the associated HTML file.

  9. Replace the existing text (which should be something like TODO: Place controls here) with This is the text content of my DHTML dialog box.

As with the control host dialog implemented earlier, this dialog box will be displayed when the user presses a button (DHTML Dialog) on the main form of the application.

To display the DHTML dialog box

  1. In Resource View, display the main form by double-clicking the IDD_MYPROJECT_FORM (located under the Dialog node of the resource file for the MyProject solution).

  2. Double-click the DHTML Dialog button, added earlier.

  3. Add the following code to the handler function:

       CMyDhtmlDlg dlg;
       dlg.DoModal( );
    
  4. Add the following code after the last #include statement in the current source file:

    #include "MyDhtmlDlg.h"
    

    This includes the .h file of the class implementing the DHTML dialog box.

  5. On the Build menu, click Build Solution.

  6. On the Debug menu, click Start Without Debugging.

When the dialog appears, open the DHTML dialog box by pressing the DHTML Dialog button.

For more information on DHTML dialogs and a more complete example, see the CDHtmlDialog class and the DHtmlExplore sample.

Creating and Consuming an Existing XML Web Service

Occasionally, a rich client application interacts with an external XML Web service by providing a rich front-end to an existing database or databases. The user is then able to interact with the data in a familiar or graphical manner.

In this step, you will create a simple XML Web service designed to run on a Web server using Microsoft Internet Information Services (IIS).

To create the XML Web service

  1. On the File menu, click New, and then click Project.

    The New Project dialog box appears.

  2. In the Project Types pane, click either Visual Basic Projects or Visual C# Projects, and in the Templates pane, click the ASP.NET Web Service icon.

  3. In the Location box, enter https://localhost/MyService.

  4. Click OK to close the dialog box and create the solution.

A common part of XML Web services is to verify each user of the application. Once you create the solution, you can implement a simple validation method. This validation routine is deliberately simple to illustrate the concept clearly.

Once the solution has been created, add a validation method to the Service1.asmx source file. To do this, right-click the Service1.asmx.cs design surface and select View Code. Replace the HelloWorld web method at the end of the file with the following code:

' Visual Basic
<WebMethod()> Function Validate(ByVal s1 As String, ByVal s2 As String) As Boolean
   Return s1 = s2
End Function

// C#
[WebMethod]
   public bool Validate(string s1, string s2)
   {
    return s1 == s2;
   }

After you have modified the source file, build the solution.

Once the XML Web service exists, you can add and configure a Web reference with the Add Web Reference dialog box.

To add a Web reference to the client application

  1. Open the MyProject solution.

  2. In Solution Explorer, right-click the MyProject project and select Add Web Reference.

    The Add Web Reference dialog box appears.

  3. Under Browse to, select Web services on the local machine. A list of XML Web services existing on the local machine will appear; select the one you just created (Service1). If the Web service is found, a service description will appear in the left pane and the Add Reference button will be activated. The URL of the .asmx file for the Web service should also appear in the URL box; it should look like this:

    https://localhost/MyService/Service1.asmx
    
  4. Click the Add Reference button.

Once the Web reference has been added, you will add a validation dialog box to demonstrate the interaction between the application and the XML Web service.

To add a validation dialog box

  1. In Resource View, right-click the MyProject project.

  2. On the shortcut menu, click Add, and then click Add Resource.

  3. Double-click the Dialog item.

  4. Double-click the IDD_DIALOG3 dialog box form.

    The MFC Class Wizard appears.

  5. Enter the following values:

    • Class name: CMyValidateDlg

    • Base class: CDialog

  6. Click Finish.

Now that the dialog box has been created, add controls to provide a validation service for the user.

To validate the user

  1. Drag two Edit control controls onto the IDD_DIALOG3 dialog box form.

  2. Right-click the first Edit control.

  3. On the shortcut menu, select Add Variable.

  4. In the Variable Name box, enter m_Name.

  5. In the Category drop-down menu, select Value.

  6. Click Finish.

  7. Right-click the second Edit control control.

  8. Add another variable (called m_Password of category Value).

  9. Double-click the OK button on the dialog box form.

  10. Add the following code to the handler function:

       Service1::CService1 *s = new Service1::CService1();
    
       UpdateData(TRUE);
       bool result = false;
       s->Validate(CComBSTR(m_Name), CComBSTR(m_Password), &result);
       if (result)
          CDialog::OnOK();
    
  11. Add the following code after the last #include statement in the current source file:

    #include "WebService.h"
    

    This includes the .h file of the Web service used by the validation dialog box.

For the validation routine to be effective, the validation dialog box must be the first user interface object to appear. If the user enters the correct name and password, the rich client application will be displayed. If an incorrect name or password is entered, the current user will be prevented from accessing the rich client application.

To implement this behavior, modify the InitInstance function of the main application class to call this dialog box first. The application continues only when the dialog box correctly exits.

To display the validation dialog box initially

  1. In Class View, expand the CMyProjectApp node.

  2. Double-click the InitInstance function to edit the function body.

  3. Add the following code before the call to the ShowWindow function of the pMainFrame object:

       // Display the validation dialog box first
       CMyValidateDlg dlg;
       if (dlg.DoModal() != IDOK)
          return FALSE;
    
  4. Add the following code after the last #include statement in the current source file:

    #include "MyValidateDlg.h"
    

    This includes the .h file of the validation dialog box.

  5. Build the solution. On the Build menu, click Build Solution.

  6. On the Debug menu, click Start Without Debugging. In the verification dialog box, enter the same text in the Name and Password edit boxes, then click OK. The rich client application will then run, displaying its main dialog box.

Creating a Setup Project

The final step in developing your Visual C++ application is creating a setup project.

To create a setup project

  1. In Solution Explorer, right-click the MyProject solution.

  2. On the shortcut menu, click Add, and then click New Project.

    The New Project dialog box appears.

  3. In the Project Types pane, select Setup and Deployment Projects, and in the Templates pane, click the Setup Wizard icon.

  4. Enter MySetup for the setup project name and click OK.

    The Setup Wizard appears.

  5. Click Next two times.

  6. Select the following output groups:

    • Primary Output from MyProject

    • Primary Output from CustomCtl

  7. Click Next two times.

  8. Click Finish

  9. On the Build menu, click Build MySetup.

The resulting file (MySetup) can be copied to a target machine for installation of the rich client application. For more information on deployment projects and the Setup Wizard, see Deploying Applications, Deployment Projects, and Deployment Walkthroughs.

See Also

Concepts

Rich Client Application Walkthroughs

Visual Studio Walkthroughs