Example 4 - Creating a User-Tool and a User-Interface


Purpose of Example


Overview of Example   In Tutorial 3, Parsing the Database and Modifying Entities, you learned how single unit fractions could be appended to text or leaders after the text or leader entities had already been created. If you knew that a particular text line was going to contain a single unit fraction, it would be more convenient to create it with the fraction, instead of adding the fraction later.

This example will create a tool which will allow the user to place text containing a single unit fraction in much the same way the Text Editor (TE) places text. The tool will prompt the user for the placement of the text (and will support snapping as well), will prompt the user for the fraction to be included with a user-defined dialog box, and will place the fraction into the Text Editor for the user to complete the necessary text entry.

Before seeing how this is done with the Visual CADD API, a little background on Windows programming is needed. Windows programming is often called message-driven or event-driven. C++ programming usually refers to messages, whereas Visual Basic often refers to events. For our purposes, they can be viewed as interchangeable. For brevity, the following will use messages to refer to either messages or events.

An example of how messages work is to think about what happens when the user presses a key on the keyboard. Windows is responsible for handling the keyboard input and constantly watches the keyboard (and its internal hardware) to know when a key is pressed. When a key is pressed, Windows checks to see what kind of key-press it was (regular, such as ENTER, or special, such as ALT+TAB) and then sends the key to the appropriate program to be processed. The key is sent to the appropriate program by sending a key-press message to the program.

Programs which run in the Windows environment must be able to receive these messages, and respond to them in the appropriate way. For example, your word processor must respond to key-press messages in different ways, depending on the kind of key that was pressed. The C key results in typing the letter 'c', whereas ALT+C results in copying the selected text.

Besides messages generated by user actions, such as key-presses or mouse-moves, Windows and other programs generate a wide range of messages to notify other programs, or other parts of the same program, that something has happened. One that we will use in this example is a message that a dialog box has been loaded by your program. When dialog boxes load, usually some kind of initialization is required. This message is your program's cue to do that initialization.

With that background, we can now say that the Visual CADD API allows programmers to create powerful user-tools by letting other programs share the messages which Visual CADD usually handles itself. The most common messages shared with user-tools by Visual CADD are mouse-clicks for placing entities and key-presses for entering data.

To create these so-called user-tools, your program must inform Visual CADD that your program is running and that it wants to share the Visual CADD messages. When your program is done, it must tell Visual CADD not to send any more messages.

The Visual CADD API provides four similar ways to tell Visual CADD to share messages. The first way is for your program to have a window or form which will receive and process the messages. Each message which is to be processed must have a specially named function to process that specific kind of message. In this first method, the special function names include the name of the window (technically, the name of a class of windows) followed by a name which describes the kind of message to process, such as MouseDown. Your program tells Visual CADD to use this window-based method with the Visual CADD API routines VCSetAlertApp and VCClearAlertApp. Our example will use this method, and it will be part of the same DLL we've been using for the previous tutorial examples.

A second way is for you to create a DLL to receive and process the messages. The DLL need not create any windows or forms. As with the window-based method, your DLL must contain a specially named function to process each specific kind of message. In this method, the special function names include the name of the user-tool followed by a name which describes the kind of message to process. Your program tells Visual CADD to use this DLL-function-based method with the Visual CADD API routines VCSetAlertAppDll and VCClearAlertAppDll.

The first method may be used with EXEs or DLLs, as long as they have a window or form to process the messages. The second method is only available for DLLs, where the advantage is that no window or form is required, and also, in the case of Visual Basic, that it can process some messages Visual Basic may otherwise not handle.

The third and fourth ways are VCSetAlertAppEx and VCSetAlertAppDllEx. These two are for external applications, usually with their own interface The third method would be used with an external application containing a window or form and the fourth method is for DLLs, but their common feature is the support of external applications with more advanced message handling.

When your user-tool is done, you can use VCAppExit to tell Visual CADD to free any unused memory and to do other house-cleaning.

User-tools usually need to prompt the user for actions. The Visual CADD API routine VCSetUserTool defines a prompt and displays it in the Visual CADD Status Bar. If more than one prompt is needed as your program goes through various steps, additional prompts may be defined by VCSetPrompt.

When your application gets messages from Visual CADD, the application must take the appropriate actions. For example, if your program gets a mouse-button-pressed or key-pressed message, your program probably needs to retrieve the location of the mouse or the particular key for further processing. The location of a mouse click is retrieved by VCGetUserToolLBDown, where LB refers to "left button," and key-presses are retrieved by VCGetCmdStr.

The rest of your user-tool simply performs the tasks it was designed to do, which usually involves other Visual CADD API routines.

This example will create a user-tool to place a single unit fraction into text, after prompting the user for the location of the text. The example will introduce a few more Visual CADD API routines.

Text entities are created by the Visual CADD API using VCAddTextEntity (or, VCAddTextEntityBP for Visual Basic and Delphi). The Visual CADD API has similar VCAdd… routines for all the basic drawing entities.

The user can select entities with a variety of tools. The Visual CADD API also provides many ways to control selections. Selections can be cleared with VCClearSelection and the current entity can be selected with VCSetCurrentSelected.

The example of Parsing the Database and Modifying Entities showed that entities may be found and made current (i.e., ready to be modified) using VCFirstSelected and VCNextSelected. When a new entity is created, it is placed at the very end, or last, in the database. The last entity may be found with VCLastEntity.

The documentation in the Visual CADD API Help file (v2.0.4 and earlier) is in error regarding VCLastEntity. The help file says that VCLastEntity will make the last entity the current entity, but it does not. Instead, VCLastEntity returns the entity handle for the last entity. The program must then use VCSetCurrentEntity with that entity handle to make the last entity current.

After creating a new text entity with a single unit fraction, the example will immediately allow the user to finish entering the rest of the text to go along with the fraction. The Visual CADD API allows your programs to use all the pre-defined tools available to Visual CADD. For example, the tool Edit (ED) will start the Text Editor (TE) whenever text is selected. The Visual CADD API routine VCEdit also runs the Edit tool, and the example will use it for editing the text.

As the user-tool example runs, it will prompt the user for input of the numerator and denominator of the fraction. This could be done in at least two ways. The first would be to use additional user-tool prompts and let the user enter the data into the Visual CADD command-line in the status bar. The second way would be to create a user-defined dialog box to accept the data.

Although either would work, our example will use a dialog box in order to illustrate how to integrate a user-defined dialog box into a Visual CADD user-tool. A secondary benefit is that the dialog box provides a natural window or form for handling the Visual CADD messages (without the window or form, we would use VCSetAlertAppDll instead of VCSetAlertApp to share the windows messages).

The simplest way to create a dialog box in Visual C++ is to use the Microsoft Foundation Classes (MFC). Dynamically linking a DLL to the MFC can cause some problems when running with Visual CADD. Therefore, it is recommended that the DLL be statically linked to the MFC.

Likewise, Visual Basic is MFC-based and the OLE DLLs created by it can also experience problems running with Visual CADD. For example, the dialog boxes in a Visual Basic OLE DLL are functional, but tabbing between controls and accelerator keys do not work. All navigation within the dialog must be done by mouse pointing and clicks. At least within the confines of Visual Basic 4.0, there is no alternative way to make an OLE DLL which may be more Visual CADD-friendly. However, the problems with dialog boxes in OLE DLLs can be easily worked around by adding additional code. Moreover, the workaround is general and the code is easily reusable by simple cut-and-paste. The example illustrates this workaround.

The dialog box will contain four controls. There will be two text boxes to accept the numerator and denominator, and two buttons for OK and Cancel. We leave it up to you to create exactly what the dialog box looks like. One example is shown below, active in a Visual CADD drawing session.


fraction dialog box


Refer to the help files of the programming language for more information if you're not familiar with creating dialogs. Specific requirements for the dialog box in Visual C++ and Visual Basic are discussed in their respective code examples.

Visual Basic Example 4 Code
Visual C++ Example 4 Code