How to Use eMbedded Visual C++ 4.0 to Create an Application for the Windows CE 4.1 Emulator (Windows CE 5.0)

 

Mike Hall
Microsoft

January 2005

Applies to:
   Microsoft® eMbedded Visual C++® version 4.0
   Microsoft® Windows® CE version 4.1

Summary: This article provides step-by-step instructions for becoming familiar with the eMbedded Visual C++ programming environment and for creating and downloading an application to the Windows CE 4.1 emulator. The article is divided into five parts, each containing a number of exercises that you can complete. It will take approximately 60 minutes to complete all the steps. (34 printed pages)

Download Windows CE 5.0 Embedded Development Labs.msi from the Microsoft Download Center.

Contents

Part 1: Creating an MFC Application for the Windows CE 4.1 Emulator
Part 2: Adding Mouse Capture and Ink Drawing to the Application
Part 3: Modifying the Application to Store and Redraw Ink
Part 4: Exploring the Debugging Capabilities of eMbedded Visual C++
Part 5: Adding Code to Save and Open Ink Documents
Summary

Part 1: Creating an MFC Application for the Windows CE 4.1 Emulator

The Microsoft® eMbedded Visual C++® development system provides a programming environment that is almost indistinguishable from Microsoft Visual C++ version 6.0. This environment, along with the Microsoft Win32® application programming interface (API) of Microsoft Windows® CE, means that programming Windows CE–based devices is quite similar to programming the desktop versions of Windows.

In this part of the article, you will use the Microsoft Foundation Classes (MFC) application wizard to create an application that you will download and run on the Microsoft Windows CE version 4.1 emulator.

For this article, you can click most of the thumbnails for larger images.

In this part of the exercise, you will perform the following procedures:

  • Create a new Windows CE MFC project
  • Configure settings in Platform Manager
  • Build and deploy the first application to the emulator

To create a new Windows CE MFC project

  1. Start eMbedded Visual C++.

    The basic user interface for eMbedded Visual C++ looks like the following illustration. If necessary, spend a few minutes looking around the tools before moving to the next step.

    Click here for larger image

    On the File menu, click New.

  2. In the New dialog box, select WCE MFC AppWizard (exe) as the item to be created.

  3. In the Project name box, type Scribble

  4. In the Location box, enter C:\LABS\EVCBASIC.

  5. With Windows CE, you are not restricted to just Intel x86 processors. Note the list of processors in the lower-right corner of the dialog box. By default, all available processors are selected. Because you are targeting only the emulator today, clear all check boxes except Win32 (WCE emulator), as shown in the following illustration.

    Click here for larger image

  6. Click OK to start the wizard.

  7. On the first page of the wizard, click Single document, ensure that the Document/View Architecture support? check box is selected, and then click Next, as shown in the following illustration.

    Selecting the Document/View Architecture support? check box causes the wizard to create two classes for the main code of your application. The Document class is intended to hold and maintain state (data), and the View class provides a graphical representation of the data. This is a one-to-many relationship where the Document class may have many associated views, each providing a different visual aspect of the data. With this architecture, data is central, so change notifications are simple and data access and storage are centralized through the document.

    Click here for larger image

  8. On the next page of the wizard, leave all the options as they are, and then click Next, as shown in the following illustration.

    Click here for larger image

  9. On the next page of the wizard, click Next, as shown in the following illustration.

    Click here for larger image

  10. On the next page of the wizard, click Finish, as shown in the following illustration.

    Click here for larger image

  11. When the summary appears, click OK to complete the wizard, as shown in the following illustration.

    Click here for larger image

Now that you have completed the wizard, you have an application that will deploy and run on the emulator, although it doesn't do anything particularly interesting yet.

Part of the benefit of using Windows CE is the flexibility to choose from a wide range of devices, and even build your own custom device and associated SDK. When developing applications by using eMbedded Visual C++, you must configure Platform Manager to indicate what platform and device you intend to download the image to. Before you deploy your project, check the settings in Platform Manager.

To configure Platform Manager

  1. Click the Build | Set Active Platform menu command.

  2. In the dialog box, select STANDARDSDK_410, and then click OK, as shown in the following illustration.

    You can also select the active platform from the WCE Configuration toolbar.

    In this case, you have only a single platform available for use. If you were to install further SDKs, this list would grow.

    Aa446907.evclab08(en-us,MSDN.10).gif

  3. Click the Build | Set Active Configuration menu command.

  4. In the dialog box, select Scribble – Win32 (WCE emulator) Debug, and then click OK, as shown in the following illustration.

    You can also select the active configuration from the WCE Configuration toolbar.

    Click here for larger image

    For each processor type selected on the initial wizard page, there are two associated project configurations: debug and release. Each configuration contains information such as the compile, link, and debug settings. You can create additional configurations or remove existing configurations through the Build | Configurations menu. Because you selected only the emulator processor, you have only two configurations.

    So far, you have set the relevant information for building the correct binary image for the target device environment. Lastly, you need to select where to place the output image, whether it's a physically connected device or the emulator. In this article, you have only one target available, and that's the emulator; but for other CPU types, there may be more than one choice.

  5. On the WCE Configuration toolbar, select STANDARDSDK_410 Emulator, as shown in the following illustration.

    Click here for larger image

Now you are ready to build and deploy your first application to the emulator. During this process, the emulator will start on the desktop computer. The startup process can take a little time.

To build and deploy the first application to the emulator

  1. Click the Build | Build Scribble.exe menu command to build and download the application to the emulator.

    The emulator should start, and then the program should download to the emulator automatically. The keyboard shortcut to recompile and download is F7.

    The emulator screen should look like the following illustration.

    Click here for larger image

    Now you need to start the application.

  2. On the emulator, double-click My Computer to see the Scribble.exe application that you have just downloaded. The following illustration shows the contents of My Computer.

    Click here for larger image

  3. Double-click Scribble.exe.

    The application starts, as shown in the following illustration.

    Aa446907.evclab13(en-us,MSDN.10).gif

    At this point, you have a fully working application — although it doesn't do much!

  4. Exit the application by clicking File | Exit, as shown in the following illustration.

    Aa446907.evclab14(en-us,MSDN.10).gif

  5. Leave the emulator running and switch back to eMbedded Visual C++ to prepare for the next exercise.

Part 2: Adding Mouse Capture and Ink Drawing to the Application

You now need to add some real functionality to the application. In this part of the exercise, you will add capture of data from the stylus or mouse and draw it as ink on the screen. You need to detect when the stylus is applied to the screen, when it moves, and when it is lifted from the screen. You will build up this functionality in steps so that you become familiar with how to use MFC wizards to speed the process of writing Windows CE code and to make best use of the MFC architecture available for developers.

In this part of the exercise, you will perform the following procedures:

  • Add state variables to the CScribbleView class
  • Modify the class constructor
  • Add the OnLButtonDown method to the CSCribbleView class to start ink capture
  • Add the OnLButtonUp method to the CScribbleView class to stop ink capture
  • Add the OnMouseMove method to the CScribbleView class to capture and draw ink
  • Compile and test the application

To add state variables to the CScribbleView class

  1. At the bottom of the left pane of eMbedded Visual C++, click the Class View tab.

  2. Click the plus sign (+) next to the Scribble classes line to expand the list of classes in your application.

    The list contains five classes, which form the template of a standard MFC Doc / View application.

    The design of a Doc / View application divides an application into a Document class that holds the data and a View class that presents the data to the user, as mentioned in an earlier exercise. The other three classes — the App class, the MainFrame class, and the AboutDlg class — provide support for the application, the top-level window of the application, and the About dialog box, respectively.

  3. Right-click the CScribbleView class, and then click Add Member Variable, as shown in the following illustration.

    Click here for larger image

  4. In the Variable Type box, type CPoint (this is an MFC class that simplifies manipulation of x-coordinates and y-coordinates).

  5. In the Variable Name box, type m_CurrentPoint

  6. Under Access, click Protected, as shown in the following illustration.

    It is always good practice to hide your data members by using the Protected option to restrict access. Class member functions can then read and update the state of your class, but external functions and objects cannot.

    Click here for larger image

    The m_CurrentPoint variable holds the last drawn point, but you also need an additional variable that indicates whether you are in a drawing state or not.

  7. In the Add Member Variable dialog box, click OK.

  8. Right-click the CScribbleView class, and then click Add Member Variable.

  9. In the Variable Type box, type bool

  10. In the Variable Name box, type m_InDraw

  11. Under Access, click Protected.

    Click here for larger image

The class wizard will edit the definition of CScribbleView to add the variable to the class. You will use this variable to indicate when the mouse input needs to be captured.

It is always good practice to initialize the state of the class before it is used, because there is no automatic guarantee of the values held in member data upon construction. The best place to do this initialization is in the class constructor, and for intrinsic data types, it is good practice to use the class initialization list.

You need to find the class constructor and modify it to clear your state.

To modify the class constructor

  1. In the left pane showing the class view for your project, click the plus sign (+) next to CScribbleView to expand the list of methods and data in the class.

  2. Double-click the class default constructor with the signature CScribbleView(), as shown in the following illustration.

    Aa446907.evclab18(en-us,MSDN.10).gif

    This step opens the ScribbleView.cpp file and shows the following constructor.

    Aa446907.evclab19(en-us,MSDN.10).gif

  3. Before the opening brace ({), add the following line of code.

    : m_InDraw(false), m_CurrentPoint(0,0)
    

To add the OnLButtonDown method to the CScribbleView class to start ink capture

  1. Right-click the CScribbleView class, and then click Add Windows Message Handler, as shown in the following illustration.

    Click here for larger image

  2. In the New Windows messages/events list, select WM_LBUTTONDOWN, and then click Add and Edit, as shown in the following illustration.

    Click here for larger image

    The class wizard adds the WM_LBUTTONDOWN function prototype to the application and opens the editor to this new function.

  3. Replace the comment:

    // TODO: Add your message handler code here and/or call default
    

    With following code:

    m_InDraw = true;
    m_CurrentPoint = point;
    

    The preceding code sets the class state to show that drawing is taking place and stores the start point for the ink.

To add the OnLButtonUp method to the CScribbleView class to stop ink capture

  1. Right-click the CScribbleView class, and then click Add Windows Message Handler.

  2. In the New Windows messages/events list, select WM_LBUTTONUP, and then click Add and Edit, as shown in the following illustration.

    Click here for larger image

    The class wizard adds the WM_LBUTTONUP function prototype to the application and opens the editor to this new function.

  3. Replace the comment:

    // TODO: Add your message handler code here and/or call default
    

    With following code:

    m_InDraw = false;
    m_CurrentPoint = CPoint(0,0);
    

    The preceding code sets the class state to show that drawing has stopped and then sets the current point to 0,0. This setting is used as a special location to show that there is no last point.

To add the OnMouseMove method to the CScribbleView class to capture and draw ink

  1. Right-click the CScribbleView class, and then click Add Windows Message Handler.

  2. In the New Windows messages/events list, select WM_MOUSEMOVE, and then click Add and Edit, as shown in the following illustration.

    Click here for larger image

    The class wizard adds the WM_MOUSEMOVE function prototype to the application and opens the editor to this new function.

  3. Replace the comment:

    // TODO: Add your message handler code here and/or call default
    

    With following code:

    if (m_InDraw)
    {
    if (point != m_CurrentPoint)
    {
    CPoint line[2];
    line[0] = m_CurrentPoint;
       line[1] = point;
       m_CurrentPoint = point;
       CDC* pDC = GetDC();
       pDC->Polyline(line, 2);
       ReleaseDC(pDC);
    }
    }
    else
    

    The else clause is intentionally undefined in this code because the wizard-generated code forms the else statement.

    The preceding code checks that you are in a capture mode (WM_LBUTTONDOWN has been called) and checks that the stylus has moved from its previous location. Then, it builds an array of two points — the last captured point and the newly captured point — and draws a line between them by using a device context for the current window.

    If you are not in a drawing mode, the default action will take place by calling the generated code on the else clause as follows.

    CView::OnMouseMove (nFlags, point);
    

You are now ready to test your application again to make sure that everything works.

To compile and test the application

  1. Click the Build | Build Scribble.exe menu command (or press F7) to build and download the application.
  2. Correct any compiler errors.
  3. If the download to the emulator fails, check to make sure that you don't still have the earlier version of Scribble.exe running.
  4. If the application is still running, click File | Exit to exit it.

After the new version is running, you should only be able to draw lines in the application by using the mouse on the emulator. Note that you have some menu commands that do nothing, and if you load another application in front of Scribble.exe and cause it to redraw all line information will be lost.

Remember to exit your application after your tests are complete.

Part 3: Modifying the Application to Store and Redraw Ink

Currently, when the screen is redrawn, the line data is lost. You need to add storage variables in the CScribbleDoc class to store captured data and add further code to the View class to call these methods at the appropriate point.

In this part of the exercise, you will perform the following procedures:

  • Add a type definition for the ink to the CScribbleDoc class
  • Add a reference to an additional header file
  • Use stdafx.h to build precompiled headers
  • Add storage for ink data to the CScribbleDoc class
  • Add the GetFirstLine method to the CScribbleDoc class
  • Add the GetNextLine method to the CScribbleDoc class
  • Add the StartNewLine method to the CScribbleDoc class
  • Add the AddPoint method to the CScribbleDoc class
  • Add a storage variable to CScribbleView for the current line
  • Modify CScribbleView::OnLButtonDown to reference CScribbleDoc
  • Modify CScribbleView::OnMouseMove to reference CScribbleDoc
  • Add an implementation to CScribbleView::OnDraw
  • Compile and test the application

To add a type definition for the ink to the CScribbleDoc class

  1. At the bottom of the left pane of eMbedded Visual C++, click the Class View tab.

  2. Right-click the CScribbleDoc class, and then click Go to Definition, as shown in the following illustration.

    Click here for larger image

  3. Above the class definition class CScribbleDoc : public CDocument, add the following two lines.

    typedef CArray < CPoint,CPoint > SingleLine;
    typedef CList < SingleLine *,  SingleLine * >  LineList;
    

    You can use the preceding definitions to refer to ink lines as a collection of points and to refer to a collection of ink lines.

The CArray and CList classes require an additional header file that is not included by default. You need to add a reference to this header file in the stdafx.h header file in order to be able to use these classes throughout the project.

To add a reference to an additional header file

  1. At the bottom of the left pane of eMbedded Visual C++, click the File View tab.

  2. Click the plus sign (+) next to the Scribble Files line to expand the list of file groups in the project.

  3. Click the plus sign (+) next to the Header Files line to expand the list of header files that your application uses.

    The list will contain seven files, which form the template of a standard MFC Doc / View application.

The stdafx.h file is used to build precompiled headers, which will be included in all compiled files in the project. It provides a way of compiling common declarations and types used throughout the project just once to speed the build process.

To use stdafx.h to build precompiled headers

  1. Right-click the stdafx.h file, and then click Open, as shown in the following illustration.

    Click here for larger image

  2. Find the line:

    #include <afxwin.h>         // MFC core and standard components
    

    Just below it, add the line:

    #include <afxtempl.h>      // MFC standard template classes
    

As you have seen, the View class is responsible for capturing information from the user and displaying that on the screen. The Document class, however, is responsible for storage and access to the data that the View class displays. At this point, there is no data stored or maintained. In the following procedure, you will add the member variables that will provide storage for the point data.

To add storage for ink data to the CScribbleDoc class

  1. In the left pane, select Class View.

  2. Right-click the CScribbleDoc class, and then click Add Member Variable, as shown in the following illustration.

    Click here for larger image

  3. In the Variable Type box, type LineList

  4. In the Variable Name box, type m_LineInfo

  5. Under Access, click Protected, as shown in the following illustration.

    Click here for larger image

  6. Click OK.

The class wizard edits the class definition of the CScribbleDoc class to add the variable to the class. Because this is a protected variable, you need to add access methods to set and retrieve data into this collection.

To add the GetFirstLine method to the CScribbleDoc class

  1. In the left pane showing the class definitions, right-click the CScribbleDoc class, and then click Add Member Function.

  2. In the Function Type box, type const SingleLine *

  3. In the Function Declaration box, type GetFirstLine (POSITION & pos) const as shown in the following illustration.

    Click here for larger image

  4. Click OK.

    The class wizard adds the public member function declaration in the header file and an empty implementation in the source file. You are then left with the ScribbleDoc.cpp file open and ready for you to type an implementation for the method.

  5. Add the following to the implementation for the GetFirstLine method.

    const SingleLine * RetVal = NULL;
    pos = m_LineInfo.GetHeadPosition();
    if (pos)
       RetVal = m_LineInfo.GetAt(pos);
    return RetVal;
    

To add the GetNextLine method to the CScribbleDoc class

  1. In the left pane showing the class definitions, right-click the CScribbleDoc class, and then click Add Member Function.

  2. In the Function Type box, type const SingleLine *

  3. In the Function Declaration box, type GetNextLine ( POSITION & pos) const as shown in the following illustration.

    Click here for larger image

  4. Click OK.

  5. Type the following implementation for the GetNextLine method.

    const SingleLine * RetVal = NULL;
    if (pos)
    RetVal = m_LineInfo.GetNext(pos);
    return RetVal; 
    

To add the StartNewLine method to the CScribbleDoc class

  1. In the left pane showing the class definitions, right-click the CScribbleDoc class, and then click Add Member Function.

  2. In the Function Type box, type POSITION

  3. In the Function Declaration box, type StartNewLine ( CPoint StartPoint ) as shown in the following illustration.

    Click here for larger image

  4. Click OK.

  5. Type the following implementation for the StartNewLine method.

    SingleLine * NewLine = new SingleLine();
    NewLine->Add(StartPoint);
    return m_LineInfo.AddTail(NewLine);
    

To add the AddPoint method to the CScribbleDoc class

  1. In the left pane showing the class definitions, right-click the CScribbleDoc class, and then click Add Member Function.

  2. In the Function Type box, type bool

  3. In the Function Declaration box, type AddPoint ( POSITION pos, CPoint NewPoint ) as shown in the following illustration.

    Click here for larger image

  4. Click OK.

  5. Type the following implementation for the AddPoint method.

    SingleLine * WorkLine = m_LineInfo.GetAt(pos);
    WorkLine->Add(NewPoint);
    return true;
    

Now that you have the data managed in the document, you need to modify the existing view methods to update and store the data in the document. You need a new class variable in the view to identify the line that you are currently drawing.

To add a storage variable to CScribbleView for the current line

  1. In the left pane showing the class definitions, right-click the CScribbleView class, and then click Add Member Variable, as shown in the following illustration.

    Click here for larger image

  2. In the Variable Type box, type POSITION

  3. In the Variable Name box, type m_CurrentPos

  4. Under Access, click Protected, as shown in the following illustration.

    Click here for larger image

  5. Click OK.

To modify CScribbleView::OnLButtonDown to reference CScribbleDoc

  1. In the left pane showing the list of members currently defined for the View class, double-click the OnLButtonDown method, as shown in the following illustration.

    Click here for larger image

  2. Modify the implementation to add the following at the end of the method, prior to the call to the base class CView::OnLButtonDown(nFlags, point).

    m_CurrentPos = GetDocument()->StartNewLine(point);
    

    This step retrieves the current document associated with the view and calls the StartNewLine method that you defined earlier.

Now you need to modify the OnMouseMove method.

To modify CScribbleView::OnMouseMove to reference CScribbleDoc

  1. In the left pane showing the list of members currently defined for the CScribbleView class, double-click the OnMouseMove method to go to its implementation.

  2. Modify the implementation to add the following just after ReleaseDC(pDC).

    GetDocument()->AddPoint(m_CurrentPos, point);
    

Now you have the point data stored in the document and updated correctly from your View class when input is captured. The next thing that you need to do is cause that data to be redrawn on the screen when it is erased. To redraw the data, you need to modify the OnDraw method to do more than just make your client area blank. You will read each of the lines from the document, and for each line, draw between each of the points on the line.

To add an implementation to CScribbleView::OnDraw

  1. In the left pane showing the list of members currently defined for the CScribbleView class, double-click the OnDraw method to go to its implementation.

  2. Replace the following line:

    // TODO: add draw code for native data here
    

    With this code:

    // Redraw the lines
    POSITION WorkPos;
    const SingleLine *WorkLine =  GetDocument()->GetFirstLine(WorkPos);
    while (NULL !=WorkLine)
    {
       // Build an array of points and draw them
       if (0 ==WorkLine->GetSize())
          break;
    
       CPoint * PointArray = new CPoint [WorkLine->GetSize()];
       for (int x = 0;x < WorkLine->GetSize();x++)
          PointArray[x] = WorkLine->operator [] (x);
       pDC->Polyline(PointArray, x);
       delete [] PointArray;
       PointArray = NULL;
    
       WorkLine =  GetDocument()->GetNextLine(WorkPos);
    }
    

You are now ready to test your application again to make sure that everything works.

To compile and test the application

  1. Click the Build | Build Scribble.exe menu command (or press F7) to build and download the application.
  2. Correct any compiler errors.
  3. If the download to the emulator fails, check to make sure that you don't still have the earlier version of Scribble.exe running.
  4. If the application is still running, click File | Exit to exit it.

After the new version is running, you should only be able to draw lines in the application by using the mouse on the emulator. With this new version, you can start other applications and then exit them and see Scribble.exe redraw its ink.

Remember to exit your application after your tests are complete.

Part 4: Exploring the Debugging Capabilities of eMbedded Visual C++

Now that you have an application that does something more than just run wizard-generated code, you can start to consider some of the key advantages that eMbedded Visual C++ provides for the developer of real applications for devices and embedded solutions. One of the main areas where development for these types of solutions differs significantly from the desktop computer is in the provision of debugging and diagnostic tools. The desktop environment benefits from the volume of developers targeting essentially the same hardware, using the same operating system capabilities, so a huge list of tools has been created over the years to help with application development. For device developers, this area has been severely lacking. In this part of the article, you will use the tools provided with eMbedded Visual C++.

So far, you have used eMbedded Visual C++ to compile and download the application to the emulator, and then run the application directly on the emulator. In this part of the exercise, you will perform the following procedures:

  • Use the built-in debugger to run the application
  • Stop the debugger
  • Test the breakpoint
  • Add a watch entry
  • Test the watch entry
  • Access the other debug windows
  • Modify variables' values at run time

To use the built-in debugger to run the application

  • From the menus for eMbedded Visual C++, click Build | Start Debug | Go, as shown in the following illustration.

    You can also carry out this command by pressing F5.

    Click here for larger image

The debugger connects to the emulator, checks the file versions, and starts the application on the emulator. The eMbedded Visual C++ environment switches to debugging mode and looks something like the following figure.

Click here for larger image

Figure 1. Debugging mode in the eMbedded Visual C++ environment

In this mode, you can see from the main application title bar that the application is currently running. The current automatic variables appear in the lower-left part of the window (there are none in the preceding figure because the application is running). The current watch variables appear in the lower-right part of the window (there are none in the preceding figure because none have been selected).

You need to stop the debugger somewhere in order to use the various options. To stop the debugger, you can use the Build | Break command if the code running is not system code, or you can set a breakpoint and wait for the break event to occur.

To stop the debugger

  1. From the menu bar, click Edit | Breakpoints to load the breakpoint window, as shown in the following figure.

    You can also carry out this command by pressing ALT+F9.

    Click here for larger image

    In the Breakpoints dialog box, you can break from one of three main categories of expression: break on location (the Location tab); break when a data expression evaluates to true (the Data tab); or break when a window procedure receives a certain Windows message (the Message tab), which is a combination of the previous two categories. It is possible to use this dialog box for setting complex conditions when a break should occur. Be aware, however, that using a data expression can severely effect the performance of the target environment because an evaluation of that data must take place after every instruction.

    In this procedure, you will set a breakpoint on location.

  2. In the Break at box, type CScribbleView::OnLButtonUp as shown in the following figure.

    Click here for larger image

  3. Click OK.

You now have a breakpoint set that will occur when the left mouse button is released from the window. Having a breakpoint on a method will not appear visually in the editor until the application is running, because the debugger can't resolve the function name until that point. However, you can set breakpoints on a specific line that will cause a visual indication to be shown during editing. The F9 key is a keyboard shortcut to set and clear location-based breakpoints.

You can now use the application and see the breakpoint work.

To test the breakpoint

  1. Switch back to the emulator.

  2. Draw a line with the mouse on the emulator, and then release the mouse button.

    You will see the code shown in the following illustration.

    Click here for larger image

    In the preceding illustration, the red circle indicates the breakpoint, and the yellow arrow shows the next statement to execute.

In the lower-left pane of the development environment, you can now see relevant data on the Auto, Locals, and this tabs. To add watch entries, you can simply drag the entries from the lower-left pane to the lower-right pane, or you can add them directly. The following figure shows the Auto tab.

Click here for larger image

Figure 2. Auto tab in the lower-left pane

To add a watch entry

  • On the Auto tab, find m_InDraw, and then drag it to the watch pane.

To see how the watch entry works, you can single-step execution.

To test the watch entry

  • From the menu bar, click Build | Step Over.

    You can also carry out this command by pressing F10.

    The value of m_InDraw changes to 0 and appears red to indicate that it changed in the last operation.

There are several other windows that can be useful for debugging an application.

To access the other debugging windows

  • Click View | Debug Windows | Call Stack, as shown in the following illustration.

Click here for larger image

Look at the call stack, memory, registers, and disassembly in turn. Note that with the emulator, registers and disassembly are all x86 specific. With another processor type, you would see the registers relevant to the target CPU and the disassembly showing the instruction set of the target CPU.

Now you can try something a little more advanced.

To modify variables' values at run time

  1. Click Edit | Breakpoints to show the breakpoints dialog box.

    You can also carry out this command by pressing ALT+F9.

  2. Click Remove All to clear all breakpoints.

  3. Click OK.

  4. Continue running the application by clicking Debug | Go, as shown in the following illustration.

    You can also carry out this command by pressing F5.

    Aa446907.evclab42(en-us,MSDN.10).gif

    Next, you will set a breakpoint on the first line of the OnMouseMove method.

  5. Scroll down a few lines in the source code to the CScribbleView::OnMouseMove method.

  6. Place the caret on the first line — if (m_InDraw) — and then press F9 to enable a breakpoint.

  7. Switch back to the emulator and, without pressing the left mouse button, move the mouse over the Scribble window.

    As shown in the following illustration, the debugger should break on the first line of the OnMouseMove method, where you placed the breakpoint. The yellow arrow shows the current line.

    Click here for larger image

    Now you will use QuickWatch to see the value of m_InDraw and change the value to true.

  8. Place the carat on the m_InDraw variable, and then click Debug | Quick Watch to open the QuickWatch dialog box (shown in the following figure).

    You can also carry out this command by pressing SHIFT+F9.

    Click here for larger image

  9. Click in the Value field, change the value from 0 to 1, and then click Recalculate.

  10. Click Close.

  11. From the menu, click Debug | Step Over to move to the next statement.

    You can also carry out this command by pressing F10.

    Because you have dynamically changed the variable's value, you have changed the behavior such that the drawing code is now invoked rather than skipped.

  12. From the menu, click Edit | Breakpoints to show the Breakpoints dialog box.

    You can also carry out this command by pressing ALT+F9.

  13. Click Remove All.

  14. Click OK.

  15. Continue execution by clicking Debug | Go from the menu or by pressing F5.

    Now, when you return to the emulator screen, moving the mouse will cause ink to be drawn as if the mouse button is pressed.

  16. Exit the application and end the debugging by clicking File | Exit.

That completes Part 4 and the main activities of this article. Move on to Part 5 if you have extra time.

Part 5: Adding Code to Save and Open Ink Documents

You still have unused menu commands in the application. In this section, you will complete the application so that it will support the File | Save As, File | New, and File | Open commands.

In this part of the exercise, you will perform the following procedures:

  • Modify the file type for saving and opening
  • Modify the File | New behavior to clear the data structures
  • Modify the File | Open and File | Save As behavior to serialize the data
  • Compile and test the application

First, you need to modify the save and open template to recognize a file extension associated with the scribble data.

To modify the file type for saving and opening

  1. At the bottom of the left pane of eMbedded Visual C++, click the Resource tab.

  2. Click the plus sign (+) next to the Scribble resources line to expand the list of resources contained in the application.

    The list contains seven categories of resources currently in the project.

  3. Click the plus sign (+) next to String Table to expand the list of string tables in the project, as shown in the following illustration.

    Aa446907.evclab45(en-us,MSDN.10).gif

  4. Double-click English (U.S.).

    The first entry contains the string used to build a doc/view template entry. This string is a specific, new line-separated format string that contains seven substrings identifying (in order): Window Title, Document Name, File New name, filter name, filter extension, Registry file type ID, and Registry file type name. For a full description of each entry, please refer to the online documentation for CDocTemplate::GetDocString.

  5. Modify the first entry in the string table with the ID of IDR_MAINFRAME and the value of 128 by double-clicking the entry.

  6. Change the string to Scribble\n\nScribble\nInk Doc (*.ink)\n.ink\nScribble.Document\nScribble Document, as shown in the following illustration.

    Click here for larger image

  7. Press ENTER to close the dialog box.

To modify the File | New behavior to clear the data structures

  1. At the bottom of the left pane of eMbedded Visual C++, click the Class View tab.

  2. If the classes are not visible, click the plus sign (+) next to the Scribble classes line.

  3. Locate CScribbleDoc and, if necessary, expand it by clicking the plus sign (+).

  4. Double-click the OnNewDocument method.

  5. Replace the following lines:

    // TODO: add reinitialization code here
    // (SDI documents will reuse this document)
    

    With this code:

    // Clear the document contents
    POSITION WorkPos = m_LineInfo.GetHeadPosition();
    while (NULL !=WorkPos)
       delete m_LineInfo.GetNext(WorkPos);
    
    m_LineInfo.RemoveAll();
    

MFC provides a robust architecture to simplify writing applications. You can see a great example of this benefit when writing save and open routines. In this case, you need to modify just one method on the document class, the Serialize method. Most MFC primitives natively support Serialize and make this job even easier.

To modify the File | Save As and File | Open behavior to serialize the data

  1. Scroll down in the document to locate the Serialize method.

  2. Replace the following line:

    // TODO: add storing code here
    

    With this code:

    ar << m_LineInfo.GetCount();
    // Serialize the document contents
    POSITION WorkPos = m_LineInfo.GetHeadPosition();
    while (NULL !=WorkPos)
    m_LineInfo.GetNext(WorkPos)->Serialize(ar);
    

    Replace the following line:

    // TODO: add loading code here
    

    With this code:

    long ElementCount;
    ar >> ElementCount;
    for (long countPos = 0; countPos < ElementCount; countPos ++)
    {
       SingleLine * NewLine = new SingleLine();
       NewLine->Serialize(ar);
       m_LineInfo.AddTail(NewLine);
    }
    

You are now ready to test your application again to make sure that everything works.

To compile and test the application

  1. Click the Build | Build Scribble.exe menu command (or press F7) to build and download the application.
  2. Correct any compiler errors.
  3. If the download to the emulator fails, check to make sure that you don't still have the earlier version of Scribble.exe running.
  4. If the application is still running, click File | Exit to exit it.

After the new version is running, you should be able to draw ink on the screen and then click File | Save As to open the dialog box that shows saving options. After you save the file, you can click File | New to clear the contents, and then click File | Open to open a previously saved drawing.

Remember to exit your application after your tests are complete.

Summary

Following is a summary of the exercises provided in this article:

  • Created an MFC application for the Windows CE 4.1 emulator
  • Added mouse capture and ink drawing to the application
  • Modified the application to store and redraw ink
  • Explored debugging capabilities of eMbedded Visual C++
  • Added code to save and open ink documents