dwTerm 1.0
Users' and Programmers' Manual

  1. Introduction
  2. Installation
    1. System Requirements
    2. Trial Version
    3. Full License Key
  3. How to Use
    1. Controls
    2. Menus
    3. Scripts
    4. plot2d.dll
    5. graph.dll
    6. draw.dll
  4. Programming
    1. Getting Started: hello.dll
    2. Start and End
    3. Inputs
    4. Behind the Canvas
    5. Miscellaneous Points
    6. Let's Scroll: scroll.dll
    7. API Reference
      1. Data Structures
      2. Functions
      3. Handlers
  5. Limits of Trial Version
  6. License Agreement

  1. Introduction

    dwTerm is a software terminal to your program. Build only the core of your project as a DLL, and run it by dwTerm in which the useful windows, functions and handler-scheme are prepared for your DLL. Spending little effort in maintaining the output on the display window, in parsing input strings, in scrolling the output, and in other stuffs, you can concentrate on your main programming.

    For example, if you want your program to receive users' commands and to simply display some texts or graphs and you don't want any complex or luxurious design of the main window with many child windows, dwTerm will satisfy you. This may be the case, especially if you are going to program to calculate or do a numerical analysis but you know nothing about creating a window and even don't want to learn it. The following features of dwTerm help your work.

    • DLLs better than EXEs

      In the case above some programmers may try to build and run an EXE file (*.exe) in a dos window. Don't do that. Build your core codes as a DLL file (*.dll), instead of an EXE, and run it by dwTerm.exe. This method not only lets dwTerm take other parts of the whole program, but also saves the computer's memory if you want to run mutiple instances of the whole program, which cannot be expected when it is built as an EXE.

    • dwTerm API

      dwTerm provides you an API (Application Programming Interface), in which various "handlers" in your DLL can be called by dwTerm at events (including the start, the end, and the command-input), and many "functions" in dwTerm can be called by your codes in the DLL. The prototypes of these routines and the related data structures are defined in a header file written in C and should be included in compliling your DLL.

    • dwTerm Script

      dwTerm can run the DLL by way of a script file where the DLL and input commands are specified. This is helpful if results you want to see can be achieved after many input commands.

    Some DLL samples are suggested with the source codes, one of which is a plotting program helpful for visual optimization of a 2-dimensional math function.

    Throughout the manual, "using" means running dwTerm, letting it load and run a DLL directly or through a script, and editting the script to see the effects. "Programming" means writing a DLL source and building the DLL binary by your compiler.

    As stated in the next chapter and implied by DLL and EXE above, your OS is supposed to be one of the Microsoft's Windows systems. If you are going to program, your compiler should support the Microsoft's Win32 API with the header files and libraries related, not only because building a DLL binary and many basic works can be done by it, but also many types in the dwTerm API's header file depend on it.

  2. Installation

    1. System Requirements

      • CPU: Intel 80486 or higher

      • OS: Windows 95, Windows NT 4.0 or higher

    2. Trial Version

      dwTerm is distributed as a compressed file, *.zip, without a full license key. That is, the zip file is for the trial version. The installation process is simple. Just extract all of the folders and the files contained in it into a folder. Then the user now has the trial license. That is, there are restrictions on some functions, before you acquire and install a full license key.

    3. Full License Key

      Go to http://www.softbattery.net and acquire a key, a small file. The installation is simple. Just put it into the folder in which the trial version is installed.

  3. How to Use

    In this chapter is described how to use dwTerm and some of the 5 DLLs' included in the package. They are found in the "plot2d", "graph", "draw", "hello" and "scroll" folders. They are not very practical and the main purpose of them is to help programmers understand the dwTerm API with the source codes as simple samples, when they read the next chapter. Hence we call them "sample DLLs". Two of them are too simple to be practical and are described not in this chaper but in the next. The sections for the DLLs are ordered so that the most practical one comes first, but the order is not suitable for learning the programming, and will be changed when you see their source codes to learn in the next chapter.

    The following is the screen-shot of the dwTerm's main window, after the default script intro.dsc (plot2d.dll) is loaded. The size and location is adjustable, and if the size is changed, the component windows to display or edit texts will be automatically resized. All the configuration including the main window's size and location, and options specified by menus, is saved in a file named "conf" and is used in the next run of dwTerm.

    1. Controls

      If a script or a DLL is loaded, The title bar shows the it's path with "Script=" or "DLL=" preceding the path, which follows the title "dwTerm". If a subtitle is provided by DLL, it appears between them. These 3 entities are separated by " - ".

      Below the menu bar is located the output display window, the input command window and the status bar. Although the DLL can output multi-line texts and graphics in the display window, the DLL may display single-line texts in the status bar. The only input from the user to the DLL transported by dwTerm is the command string in this version. Other inputs, from the mouse, the keyboard and so on, will be added later. There is a button on the right of the command window. Either press it, or press the Enter key in the command window, to input the command string after typing.

      Right after a DLL is loaded (by menus or at the dwTerm start-up) or just before it is unloaded (by menus or at the end), dwTerm may call some routines in the DLL called "handlers". Right after you input a command string, another handler may be called. Each handler has the specific name and is not called if not found in the DLL.

      When a handler is called, the status bar shows a text saying that it is called. In case of the "Command" handler, the text is headed by "dwTerm Input 8: " if the command is the 8th one. Right after the Command handler finishes it's work, the bar may show the result string with the header "d8: " if the command is the 8th one. If a handler does not inform dwTerm of any result to be displayed in the bar, the bar text will not be changed. The "Start" handler, the last one of the handlers called right after loading, also can show a result, with the header "d0: ".

    2. Menus

      It is recommended for you to associate the extension "dsc" with dwTerm in your system, since you can then run dwTerm and load a script file (*.dsc) just by double-clicking the file in a folder window. Just double-click any script file and follow the dialog boxes from the system, to associate "dsc" with dwTerm. You may associate "dll" too.

      Unless you run dwTerm by (double-clicking) a script or a DLL in a folder, dwTerm searches the dwTerm folder (where dwTerm is installed) for a default script named "intro.dsc" and tries to load it if found.

      The [File]->[Load...] menu lets you load a DLL or a script. A file with the extension "dll" (*.dll) is loaded as a DLL, and any other file is loaded as a script. Therefore a script file extension does not have to be "dsc".

      The [File]->[Reload] menu reload the file. You may use this menu frequently when you edit the script to see the results.

      Use the [File]->[Edit...] menu to let your editor open the script file loaded. You may not use this menu after you loaded the DLL directly (Will you? Why?).

      The DLL is unloaded, just before it or another DLL is loaded by the 2 menus above, or when dwTerm ends (by the [File]->[eXit] menu or by other ways). The DLL is also unloaded by the [File]->[Unload] menu. In any case, a DLL (the "End" handler in it) can refuse to be unloaded for some reason (the DLL programmer may need you to wait or input something for example). If the DLL programmer is gentle, a message box will be popped up or a message will appear in the display window, in that case. Since dwTerm does not end before unloading, you sometimes cannot but kill dwTerm if you use a bad DLL or if you don't want to follow the DLL's message.

      You can specify the script editor by the [Option]->[Editor...] menu. It is recommended not to check the check-box in the dialog box issued by the menu, since you are recommended to associate the script file extension with dwTerm. In the dialog box you can set the path of your text editor in the "Application" edit box, by browsing. The command line string (NOT to be confused with the dwTerm command window string) for the editor can be specified. Use "%m" to represent the script file path, and use "%%" if you need "%".

      The [Help]->[Manual...] menu opens this manual.

      The [Help]->[About...] menu shows the version, the copyright and the license status.

    3. Scripts

      A dwTerm script is a text file, in which the DLL to load and a set of command strings to input automatically right after loading are specified. The syntax is simple, as you may recognize in "intro.dsc" included in the package. Begin a line with a blank to make it meaningless to dwTerm and to write a note or comment. Therefore the title in the first line in "intro.dsc" is meaningless, for example.
      *** Default dwTerm Script *** ("default", since dwTerm will search the dwTerm folder for this file "intro.dsc" if none specified at the start-up.) (Any lines like this is meaningless, because they begin with a blank.) plot2d\plot2d.dll dwTerm Script Commands p xx -0.35 p yy -0.7 p xy 0.7
      ...

      The first meaningful line tells the path and the file name of the DLL. If the path is omitted, the path of the script will be used. That is, you can omit the path if the DLL and the script are in the same folder, as in every sample in the package except plot2d.dll (intro.dsc).

      The command string lines come next, preceded by the break line "dwTerm Script Commands".

      Loading a script means for dwTerm to read it, load the DLL specified in it, and let the DLL process the commands specified in it.

      Although scripting is regarded as "using" rather than "programming" in this manual, IDE(Integrated Development Environment) is more helpful for you in scripting, than modifying the script in a simple editor and using the [File]->[Reload] menu. Configure your IDE, for it to run a script file by dwTerm when you press a menu or a shortcut key while editing it.

      The next 3 sections describe some of the sample DLLs. You can run them by menus, or by double-clicking the scripts contained in the corresponding folders. The latter lets you see the same outputs as the screenshots shown in the sections, while the former show poor outputs, since the scripts contain some commands.

    4. plot2d.dll

      The default script "intro.dsc" in the parent folder (the root folder where dwTerm is installed) runs this sample. If you don't have any practical interest in this sample, it just provides a beautiful(?) picture you see when you start dwTerm not by way of a specific script. If you even don't think so, you may modify or remove the script.

      This sample calculates 2-dimensional 2nd order function

      f(x, y) = Axxx2 + Axyxy + Ayyy2 + Axx + Ayy + A1
      to paint dots, the colors of which depend on the calculated values as follows.
      • "+" color when f > z
      • "0" color when |f| ≤ z
      • "-" color when f < -z

      There are 4 brushes for "+", "0", "-" and "e"(erase, i.e. background) colors. The colors are specified and the brushes are created or deleted, by commands. The "e" brush is initially created and used to erase all before the first command. The parameters of the function are specified by commands. The graphics region is defined, created and deleted, also by commands.

      The commands are defined by examples as follows.

      "brush commands": sets z and brushes, and erases over the graphics region. All the commands shows values about z and brushes, on the status bar, where the data for a brush are displayed as, for example for the "+" brush, "+: ffff00" if the brush exists or "+: N(ffff00)" if not. The 3 bytes in the hexadecimal mean the the blue, green and red intensities, from the left, so that the example value (ffff00) stands for a cyan color.

      • z 0.5
        sets z = 0.5 for example.
      • b + n
        destroys the "+" brush. The same goes for the other 3 brushes if "+" in the command is replaced.
      • b + c 0xffff00
        sets the "+" color = 0xffff00 for example, and creates the brush. The same goes for the other 3 colors if "+" in the command is replaced.
      • b +
        creates the "+" brush. The same goes for the other 3 brushes if "+" in the command is replaced.
      • b
        just shows the data on the status bar.
      • z
        just shows the data on the status bar.
      • e
        Erases anything over the region, with the "e" brush.

      "plot commands": sets the function parameters and paints dots. All the commands shows parameters, on the status bar.

      • p xx 3.5
        sets Axx = 3.5 for example. The same goes for the other parameters if "xx" in the command is replaced.
      • p
        just shows the parameters on the status bar.
      • d
        paints dots over the region, using the brush according to the function value for each dot. If the brush does not exist, the dot will not be painted, so that the present dot color will be kept unchanged, which enables the accumulated drawings of ellipses done by the command strings in "intro.dsc" where only the "e" and "+" brushes are created.

      "region commands": sets the graphics region by setting the dot size and the mathematical coordinates. All the commands shows the dot size and the coordinates, on the status bar. The dot size "t=4" for example is the length of each edge of each square dot, and the coordinates are shown as "r=(-75 -50 75 50)" for example where the first pair is the x, y coordinates of the bottom left corner and the second pair is those of the top right corner. Note that the dot size is measured in pixels, and that the coordinates are measured in dots, so that the size of the graphics region in this example is 604 x 404 in pixels

      • t 3
        sets t = 3 for example, and runs the "e" and "d" commands, if 3 is new.
      • r -10 25 100 90
        sets r = (-10 25 100 90) for example, and runs the "e" and "d" commands, if any coordinate value is new.
      • t
        just shows the size and coordinates on the status bar.
      • r
        just shows the size and coordinates on the status bar.

    5. graph.dll

      This draws sine functions sin(Angle-Phase) versus Angle with various Phase. The commands in the script file contained in the folder generates 2 overlapped graphs with different Phases, as shown above.

      The commands are defined as follows. All the commands except "e" shows Phase on the status bar.

      • e
        erases all and redraws the title and axis.
      • p 90
        sets Phase = 90 deg for example.
      • p
        just shows Phase on the status bar.
      • d
        draws the graph.

    6. draw.dll

      This is the same as graph.dll except that the title and the axis are absent.

  4. Programming

    This chapter shows how to make a DLL for dwTerm and what happens between dwTerm and a DLL. If you don't know what is a DLL and how to build one, the early parts of the first section can be a tutorial. Buiding a DLL is as easy as to bulid a *.exe. Most parts of this chapter use the source codes of all the five sample DLLs to introduce you to the dwTerm API. The usage of three samples were described in the previous chapter, and the other two are here with their names in the section titles.

    You are supposed to be a little familiar with C to understand the samples' source codes. Data types and functions of the Microsoft's Win32 API are also used in the codes. Even if you are not familiar with them, comments in the sections for samples may let you recognize how to use them. If familiar with the Win32 DLL and API, you can skip to the dwTerm API Reference section.

    1. Getting Started: hello.dll

      If you know what is a DLL, what is a run-time DLL and how to build it, skip the following 3 paragraphs. A DLL is useful, not only because you can program the core of your work into it and dwTerm works as the other part, but also because of it's nature described below.

      If your programs have same functions (routines), you may use them in the form of static libraries. Although static libraries help your works, the results of the works, that is, *.exe files, contain same function codes, so that the computer's memory will have duplicated codes when those programs run simultaneously. Is there any way not to waste ? The DLL(Dynamic Link Library) is an answer. Build a DLL which contain fuctions and related global variables. Then the OS keeps in the memory only one copy of function codes while the global data space is prepared for each program instance.

      There are 2 types of dynamic linking, "load-time" and "run-time". DLLs in your OS are automatically loaded when an application(*.exe) is loaded into the memory to run ("load-time"). Some applications also provide their own DLLs in the package. Load-time DLL developers should generate and distribute some files called import-libraries, for application developers to include the files in the link stage of the compiler.

      Run-time DLLs can be loaded any time after the the application is loaded, and application developers don't need anything related to them in the link stage of the compiler. Here is a DLL souce code as an example.
      #define EXPORT __declspec(dllexport) EXPORT char *dwTermH_Start (char *CmdLine, char **Title) { return "Hello!"; }
      A function in a DLL is said to be "exported" if it can be called by other module (*.exe for example). In this example the function is exported by the definition of "EXPORT" and making it precede the function. This example is the source hello.c of hello.dll, the most simple sample in the package. All the samples are compiled and linked by MinGW, and you can see the options used in compile.bat and link.bat in each sample folder. You can use the batch files in your IDE or dos-window with some modification (especially the compiler path). The export method and compile/link options may be different for other compilers. Refer to your compiler's manual.

      Now, let's turn to what are related to dwTerm. After loading a run-time DLL, dwTerm calls a set of functions in the DLL which are called dwTerm "handlers". A handler is called, right after the DLL is loaded, just before unloaded, or when other events (user inputs, for example) occur. It is not called, if not found. The name and the prototype of each handler, when it is called, what arguments transfered mean, and what it should return, are listed later in this chapter.

      In this sample, there is only one handler, named dwTermH_Start which is also called the "Start" handler. It is one of the "start" handlers which are called right after a DLL is loaded. In generall you make the handler initialize various variables or system resources to be used later, but the handler in this sample does nothing but returning a string pointer. dwTerm displays the string on the dwTerm status bar. If the handler does not want this feature, it should return NULL. The header file windows.h in your compiler package should be included to use NULL because it is a Win32 constant meaning a "null pointer", but 0 is OK instead if you dont want to include the header.

      In the former parts of this section, an "application" meant a *.exe file which uses DLLs. But you may not say that dwTerm is an application using your DLL as a library. Instead we may call your DLL an "application DLL" which uses dwTerm API, not only since the DLL uses the dwTerm API handler scheme introduced in this section, but also since the DLL uses the dwTerm API functions introduced in the next section where you can recognize how a DLL can call a function provided by *.exe.

    2. Start and End

      All the sample DLLs' source codes in the package except hello.c contain the following variable and handler.
      DWTERMF_Graphics *dtg; EXPORT void dwTermH_FunctionGroup_Graphics (DWTERMF_Graphics *fg_g) { dtg=fg_g; }
      This handler is called before dwTermH_Start, to transfer to you the pointer to a group of dwTerm API "functions", so that you can call a function aftn(a, b) for example by
      dtg->aftn(a, b)

      The function prototypes with the related data structure types, and the "Function group" data structure type DWTERMF_Graphics in which function pointers are contained to form a group, are defined in the header file graphics.h in the "include" folder of the package, which you should include in your source codes to use those functions and structure types. Although you may open and read the header file, to see what functions belong to the group or to see the forms of functions, you may prefer the reference section in this chapter where all of them are listed with the precise meanings of data structures and the full description of each function about what it does and returns. Although there is only one group now, more groups of functions will be added to next versions, with the corresponding header files.

      Now, you are informed of how dwTerm and an application DLL can work together, by the previous section and the paragraphs above. Let's open and start to learn the source file draw.c of draw.dll. Note that windows.h in your compiler package is included before graphics.h, since some members or arguments of many data types and prototypes in the dwTerm API are dependent on types defined in the Win32 API.

      Early in the file is declared a structure, the type of which is DWTERMD_Canvas and we also simply call "Canvas". We draw on it when we need to, and the output display window copies it when the window is exposed to the user. We call such a window a "dWin" and there is one and only one, as a child window of the main window of dwTerm, called the display window in the previous chapter. Without the dWin and canvas concept provided by dwTerm, the programmer should not only draw when the contents needs modification, but also draw the same contents again whenever the user restores the window from the minimized state or from being invisible under other windows. In other words, dwTerm frees the programmer from processing the "update messages" from OS issued in the latter cases.

      The fourth member "size" in the canvas structure is a Win32 structure POINT with the members x and y meaning the canvas width and height in pixels respectively. The area in dWin('s DC) to copy the canvas is defined to be the rectangular area of this size at the top-left in dWin, and dWin will paint the other parts with it's internal gray brush if they need to be updated. The first 3 members in the canvas structure initialized with NULLs in this sample are handles of some objects, as described in the next paragraph.

      In the dwTermH_Start handler, the "hWnd" member of the canvas is assigned the handle of dWin, using dtg->GetDWin. Then dtg->CreateCanvas "creates the canvas", which means that it creates a memory DC compatible with the dWin's DC. A DC(Device Context) is a Win32 GDI (graphics part of Win32 API) object where we draw or paint. While a window's DC provides the contents we see in the window, a memory DC is a virtual one (invisible). When we say "dWin copies the canvas", we mean that dWin lets it's DC copy the contents on the memory DC. One more GDI Object, one of the GDI graphics objects, a bitmap, should be created and "selected" on the memory DC before we draw, which are the last steps run in the function dtg->CreateCanvas. Therefore dtg->CreateCanvas sets the "hDC" and the "hBm" members of the canvas structure with non-NULL values, which are the handles of the memory DC and the bitmap respectively. But you may not be interested in hBm unless you want to pack what you drew into a bitmap file.

      dtg->RegisterCanvas informs dWin of the memory DC, for dWin to be ready to copy. The function should not be run before the canvas is created, since there will be a fatal error from OS if dWin tries to copy the canvas('s memory DC) that does not exist.

      The last function related to the canvas in the dwTermH_Start handler in the present sample is dtg->CopyCanvas. It makes dWin copy the canvas right now. If the second argument, a brush handle, is not NULL, all over the canvas is painted ("erased") with the brush before copying.

      A brush is also a Win32 GDI graphics object with the handle. The structure type DWTERMD_SolidBrush and related functions provide you an easy way to create and destroy a brush of a solid color and to maintain it's handle and color. A hexadecimal color value 0x11aacc for example means a color with 0x11, 0xaa and 0xcc being the blue, the green and the red intensities respectively. The second members "clr" of the structures (EraseBr and DrawBr) in this sample are initialized with 2 different colors. The other members "h" of the structures initialized with NULLs will aquire handle values after dtg->CreateSolidBrush create the brushes.

      The dwTermH_End (briefly we call "End") handler is called just before dwTerm unloads the DLL. You may do anything you want to be done at the end of your work. If you find some problem, you may return FALSE to refuse to unload. In generall, you need to free memory blocks and delete GDI objects here, which were allocated and created by you. In this sample, the 2 brushes are deleted by dtg->DeleteObject. Internally the function deletes the object using a Win32 function DeleteObject and resets the handle (set NULL on it). Since dtg->DeleteObject is used for not only brushes but also some other sorts of GDI graphics objects including fonts, the type-casting "(HGDIOBJ *)" is required for the argument (the pointer to a specific object's handle) to avoid the compiler's warning.

      The canvas too is "deleted" in the dwTermH_End handler, by dtg->DeleteCanvas which deletes the memory DC and the bitmap, with NULLs set on the handles. Be sure to run dtg->UnregisterCanvas before dtg->DeleteCanvas, to tell dWin not to copy any canvas from now on, unless you register another canvas. The order between the functions is important. (The reason is similar to that for the order of creating and registering).

    3. Inputs

      The other handler you can see in draw.c is dwTermH_Command (briefly we call it the "Command" handler). dwTerm calls this handler whenever the user enters a command string. Instead of simply informing you of the pointer to the whole string, it helps you process the string, by the 2 arguments. A string consists of one or more "tokens", where we define a token to be a string without any blank. The first argument, nToken is the number of them. The pointers to each token with a NULL added are contained in the array pointed by the second argument, Token.

      This handler can show a message on the dwTerm status bar, in the same way as dwTermH_Start can. Therefore this sample shows error messages when the command string is wrong, or shows the value of Phase when the command string is "p" (with or without the Phase value) or "d", by returning pointers to those messages (See the three macros used in the handler).

      The codes for the "d" command in the handler are worth mentioning. The dtg->PaintDot function draws a filled rectangle. Since the first argument is a DC handle and the last argument is a brush handle, it can be used also in any case without dwTerm-specific canvases or brush structures. The 2nd and the 3rd arguments specify the horizontal and the vertical coordinates of the rectangle's top left corner. The 4rd and the 5th arguments are the width and the height. The coordinates and the sizes are measured in pixels and the coordinate convention is also that of GDI: The origin of coordinates is the top left corner of the DC, with the horizontal coordinate increasing to the right and the vertical to the bottom.

      Note that, after the graph is drawn by the loop using dtg->PaintDot, the handler runs dtg->CopyCanvas (with the second argument being NULL), to let dWin copy the canvas right now. Don't forget that the canvas (the memory DC) is invisible.

      Let's turn to graph.dll, an improved version of draw.dll. It draws not only the same sine graphs, but also the angle axis and the title. Right after "erasing" (by the "e" command or by the Start handler), the the axis are redrawn by the routine "DrawAxis" in graph.c. To display a text, the routine uses 2 Win32 functions, SetRect and DrawText. The last 4 arguments of SetRect function sets the members of a Win32 structure RECT pointed by the first argument. In general RECT is used to express a rectangle and the members are "left", "top", "right" and "bottom". DrawText displays a text pointed by the second argument, on the DC whose handle is pointed by the first argument, inside the rectangle (a RECT) pointed by the 4th argument. Just use -1 for the 3rd argument if the text string is NULL terminated. There are many contants available for the last argument which specifies various effects on the appearance, but the constants introduced in our samples may satisfy general cases. DT_CENTER and DT_RIGHT specifies the horizontal position of the text in the rectangle in the way implied by the name.

      When you express a rectangle in GDI by 4 coordinates, don't forget that the "rectangle", i.e. the geometrical object we intend to represent by the expression does NOT include the right and the bottom edges of the expression. Most of GDI functions including those introduced in this manual have this convention, when they work (paint, update, ...) with rectangles given as arguments. If you forget this, the result can differ from what you intend, by one pixel both horizontally and vertically.

      The font, another kind of GDI graphics obejct, is introduced in this sample. The DWTERMD_Font structure and the related functions let you easily create a font and maintain it's handle and parameters. Like DWTERMD_SolidBrush, the first member "h" of the structure is the handle, and the others are parameters used in the creation. The first parameter "size" is the font size, expressed by a POINT structure where the members x and y mean the width and height of a character. The second parameter "weight" is the weight or thickness, and we generally call 700 bold and 400 normal. The next 3 parameters "fItalic", "fUnderline" and "fStrikeOut" are BOOLEAN values, TRUEs of which make the font italic, underlined and striked out respectively. The last parameter "face[LF_FACESIZE]" is the font (typeface) name, and it is pleasant to recompile and test after modifying the font name in graph.c into other famous font names that you may use in your editor, wordprocessor or HTML file.

      After creating a font, it should be "selected" on the DC before you use DrawText. The font for the axis (the axis name and the graduation numbers) is selected early in DrawAxis, by Win32 function SelectObject. The title is drawn in the Start handler after the font for it is selected.

      Other important Win32 functions you need to know for a DC before drawing texts on it are SetTextColor and SetBkMode. The former specifies the text color, and the latter with the constant TRANSPARENT into the last argument makes the background of the text untouched (i.e. disables the "text background color" which fills the small rectangle encompassing each character and is specified by SetBKColor). Note also that "-mwindows" is added to the compiler's link option (MinGW) for this sample. Without it, errors in the compiler's link-stage happen, due to the Win32 functions introduced in this and the previous paragraphs.

      The next aspect of graph.c worth mentioning is that dtg->CopyCanvas is not used in the routines for the "e" and "d" commands. While the function lets dWin copy all in the canvas, the routines are going to let dWin copy only the graph area represented by the RECT structure rcGraph, since they erase and draw the graph only in that area. A Win32 function InvalidateRect satisfies this purpose and dtg->CopyCanvas also uses it internally. It lets a window update(draw) a rectangular part of it's DC area, and therefore dWin('s DC) will copy the corresponding part of the canvas ('s memory DC). The last argument of the function, TRUE or FALSE, is meaningless for dWin. Note that the "e" command routine calls a Win32 function FillRect to erase all on a rectangular area in the canvas, since we decided not to call dtg->CopyCanvas which uses the function internally as dtg->PaintDot does.

    4. Behind the Canvas

      Other aspects of graph.c are a little subtle, as decribed in this section. Some of you who are not familiar with the Windows programming may not know why there is no statement for canvas-copy operation after DrawText and DrawAxis are called in the Start handler. The answer is that the copy operation ordered by dtg->CopyCanvas stated before them to erase all will be done after the handler returns, although the previous 2 sections said that such an operation runs "right now". The next 2 paragraphs have more in detail.

      A window runs an internal routine when it receives a "window message". Hence the Windows system is called "message-driven". There are various messages, each of which is issued by the system when the corresponding event happens. The "update-message" which tells the window to update(draw) it's DC, is issued at various events including when the window is created, when the user restores it from an invisible state, and when the program itself orders. Like many other messages, this message will not arrive at the window if the window is busy in processing another message. If there are more than one orders during this period, the areas to be updated will be combined into a union area to be informed to the window.

      A dwTerm handler in your DLL is called in the routine in dwTerm which processes the corresponding message. Therefore, in view of the previous paragraph, one statement for copy-operation is sufficient in a handler and it's position in the handler is not important, even if there are many painting or drawing operations in the handler so that many areas in the canvas need to be copied, as far as the area requested in the one copy-operation covers all the areas.

      Furthermore, no statement for copy-operation is needed in the Start handler, since the handler is called in the routine for the message which is issued when the dwTerm main window and dWin is just created (not visible yet and there will be shortly the first update-message to make it visible as commented in the second paragraph). Therefore the copy-operation order issued in dtg->CopyCanvas stated for erasing in the Start handlers of samples is not needed actually.

    5. Miscellaneous Points

      Let's turn to plot2d.dll. The size of canvas structure in plot2d.c is omitted in the initialization of the structure, since the routine "Init" will determine it by the calculation based on the graph's dot-size and mathematical coordinate ranges. Note that the mathematical coordinate system is different from that of GDI. In the former, the vertical coordinate increases from bottom to top, and the origin can be changed by a user input. The transformation between the two system is found in the routines Dot and Init. Note also that dtg->PaintDot does not paint if the brush does not exist (i.e. the last argument is NULL).

      All the creation functions in dwTerm run internally the corresponding deletion functions. Therefore, before the creation of a new canvas in the Init routine in this sample there is no dtg->DeleteCanvas. The function is run internally in dtg->CreateCanvas to delete the old canvas before creating a new one. Similary, the creation functions of the GDI graphics objects run internally dtg->DeleteObject. You may have one more question about canvases "Why does the routine Init not register the new canvas?". The answer is that dWin is informed of not the memory DC handle but the pointer to it by dtg->RegisterCanvas.

      If you don't know why dtg->CopyCanvas is stated before dtg->CreateCanvas in the routine Init as well as after the creation, rebuild the sample after deleting dtg->CopyCanvas stated before dtg->CreateCanvas, to see what will happen: You will see the contents of the old large canvas remain as the background of those of the new canvas unless the user (you) manually updates dWin (by minimizing and restoring the main window for example), when you change t from 2 to 1 for example. The answer is that the parts of the old area in dWin which do not belong to the new area should be updated too so that dWin paints over them on it's own (with the internal gray brush).

      This and the next paragraph are about the arguments of the Start handler, which are ignored in the previous samples. The second argument is the pointer to an internal string pointer in dwTerm and the string will be inserted into the title bar as the "subtitle". The internal pointer is NULL unless touched by the handler and there will be no subtitle in that case. This sample lets the internal pointer copy the pointer to "Plot 2D 2nd Order". You may ask "How long does the pointer value have to be kept valid?". dwTerm use it only once to write the whole string in the title bar right after the handler returns. Therefore you can use the memory space for the string in other works or destroy (free) it, in any handler which may be called after the Start handler. The life of the pointer value returned by the Start or Command handler for the message on the status bar is similar: dwTerm use it only once right after the handler returns.

      The first argument of the Start handler is not used in any sample. It is the pointer to the part of the command line string (Do NOT confuse with the dwTerm command window string), following "dwTerm", blanks, the file name (the script or DLL with the path), and blanks. For example, if you run dwTerm by entering "dwTerm my.dll abc def" in a dos window or in a batch file, we call the string a command line string. Then the first argument of the handler points to "abc def", to help you program the command line option of your DLL.

      Do you know why there is no statement for canvas-copy operation after Draw in the "t" and "r" command routines"? If not, read the previous section again.

      We close this section by adding more aspects of the mechanism discussed in the previous section. In the Start handler in this sample, the canvas is registered after dtg->CopyCanvas in Init, which makes no problem since updating will happen after the handler returns. Similarly, although the "Start and End" section for draw.c strictly recommended you to keep the order of creating and registering a canvas in the Start handler and that of unregistering and deleting in the End handler, there will be no error even if any pair is reversed WITHIN the handler.

    6. Let's Scroll: scroll.dll

      All the samples in the package are not very practical and their main purpose is to help you learn the dwTerm DLL programming. This sample, scroll.dll, as well as hello.dll is not practical in any way, but it's source codes may serve as an important guide to how programmers can easily scroll & display texts and graphics.

      The commands to use this DLL are defined as follows.

      • q
        displays a single line text, with scrolling if needed.
      • a
        displays a single line text, with scrolling if needed.
      • n
        erases all and displays 2 lines of text at the top. Since the 1st line is long, it may break into more lines.
      • g
        draws a sine graph, with scrolling if needed.

      In scroll.c, DWTERMD_PrintCanvas structure is introduced and we simply call it "PrintCanvas". The first member "cv" is a canvas, and the others control scroll & display on the canvas. The third member "rc" is the RECT "display area" and the second member "p_hBr" is the pointer to a brush handle for erasing all in the area. The last member "fmt" is to control how to display text, and is identical to the last argument of the Win32 function DrawText, which was introduced already in the Inputs section. One more constant, DT_WORDBREAK is introduced in this sample. Rebuild this sample, deleting this constant, to see what happens: A long line of text output in the "n" command routine will not break into more lines, and only a part of it will be visible inside the right border of the display area.

      The "g" command routine describes how we can scroll & display, and helps you understand what happen internally in dtg->Print which is used for the "q", "a", and "n" commands to scroll & display texts very easily. The first step in the scroll & display process is to adjust the display area size. Do not touch the top edge, unless you want to initialize it as in the "n" command routine where we change the top edge to let it top the canvas. Generally, just adjust the left, right and bottom edges to obtain your display area size.

      Then run dtg->Scroll, since the area's bottom edge may invade the canvas bottom. This function moves up, all the contents drawn above the horizontal line containing the area's top edge, and the area rectangle, until the area bottom or top edge meets the canvas's corresponding border. The function lets dWin copy now all above the moved rectangle. Now you are ready to draw on this scrolled rectanglular area.

      After drawing, run dtg->CopyShift, to let dWin copy the area now and to move down the rectangle by it's height. This is the final step of the process, and the rectangle will be used in the next process. All these steps are run in dtg->Print for a text. Internally it calls DrawText twice to display text. The second call uses the fmt member of the structure as the last argument. The first call uses (DT_CALRECT | fmt) instead of fmt to calculate the area size for the text. But the right border of the new rectangle calculated is overridden by the old value to keep the width unchanged.

      Therefore the area width can be changed only by you. While this sample uses a constant width (equal to that of the canvas), you may vary it in your codes, according to the kind of the contents to display, for example. In that case, be careful before drawing, since the left and the right parts outside the scrolled rectangle may contain the previous contents. Perhaps you may erase them before drawing, for example, by SetRect and FillRect for a local temporary RECT variable where SetRect sets it with (0, prc.rc.top, prc.cv.size.x, prc.rc.bottom).

    7. API Reference

      In this section all the dwTerm functions, handlers and data structures are listed and described, for you to program a run-time DLL for dwTerm. The function prototypes and the structure types are defined in graphics.h in the package ("include" folder) and it should be included in your DLL source. Many of them refer to types and constants defined in windows.h or more files in your compiler package, and they should be included before graphics.h.

      Each structure type name includes the prefix "DWTERMD_" or "DWTERMF", and each handler has "dwTermH_", to avoid compile-errors due to the same names in your source or other header files. The functions names don't have such a prefix, because (the pointer to) each function is a member of a special data structue and can be called in your codes only with "dtg->" preceding the name, where dtg is a variable containting the pointer to the structure obtained by a special handler. Any types or functions without those prefixes or pointers belong to the Win32 API or the C library. As well as documents in your compiler or others, comments in other sections in this chapter for sample codes may help you understand them.

      The meanings and roles of arguments are omitted in the descriptions of the Functions and Handlers subsections, if they are apparent by their names or data types. For the meanings of Win32 data types, refer to your Win32 API references or this chapter where they are used in the following Data Structures subsection and in other sections for samples. But, generally you don't have to, if you keep in mind that the prefixes "H" in a data type and "h" in a name usually mean "the handle of".

      1. Data Structures
        DWTERMF_Graphics is a special structure type, in which a group of dwTerm function potinters are listed, so that a function can be called in your DLL codes by the method described in the second paragraph above in this section. We call this a "function group" structure. This structure, all the function types in the group and related structure types are defined in one header file. There is only one group now, the "Graphics" function group that all the functions in this section belong to. More groups, and more functions in this group will be added in some of the next versions. typedef struct DWTERMD_SolidBrush_tag { for creating, destroying, and using a solid brush. HBRUSH h; Handle of the brush. Non-NULL if it exists, and NULL if not. COLORREF Clr; Color of the brush. } DWTERMD_SolidBrush; typedef struct DWTERMD_Font_tag { for creating , destroying, and using a font. HFONT h; Handle of the font. Non-NULL if it exists, and NULL if not. POINT size; Average size(width=size.x, height=size.y) of characters, in pixels. int weight; Thickness. 0 to 900. In general, 400 is normal and 700 is bold. BOOLEAN fItalic; BOOLEAN fUnderline; BOOLEAN fStrikeOut; Whether the font is italic, underlined, or striked out, respectively. TRUE if it is, and FALSE if not. TCHAR face[LF_FACESIZE]; Type-face name (font name). } DWTERMD_Font; typedef struct DWTERMD_Canvas_tag { for creating, destroying, and using a memory DC with a special window. HWND hWnd; Handle of a special kind of window called "dWin", which simply copies the contents in the memory DC when it is to be redrawn (when the user unveils it by removing other windows over it for example). In this way, you draw only when you want to change the contents. One (and only one) dWin is the display window contained in the dwTerm main window. HDC hDC; Handle of the memory DC compatible to the dWin's DC. Non-NULL if it exists, and NULL if not. HBITMAP hBm; Handle of the bitmap compatible to the dWin's DC, to be selected into the memory DC. Non-NULL if it exists, and NULL if not. To "draw on the canvas('s memory DC)" means to draw on the bitmap. POINT size; Width(=size.x) and height(=size.y) of the bitmap, in pixels. } DWTERMD_Canvas; typedef struct DWTERMD_PrintCanvas_tag { for scroll & display on a canvas. DWTERMD_Canvas cv; Canvas. HBRUSH *p_hBr; "Erase" brush handle pointer, to erase all on the display area (rc). RECT rc; "Display area" in the canvas('s memory DC), which we move and in which we display. UINT fmt; Text display format, to be used when a dwTerm function for text is called. DT_LEFT | DT_WORDBREAK can be used for general purposes. Since the function internally use a Win32 function DrawText, refer to the related reference for other values. But some values, DT_CALRECT and DT_NOCLIP are not recommended since they may not be suitable to the scrolling mechanism that this structure and the related dwTerm API functions perform. } DWTERMD_PrintCanvas;

      2. Functions
        "dtg->" is added to each prototype just to tell you that the function can be called in that way, where dtg is the function-group pointer obtained by the corresponding special handler. ------------- on GDI Graphics Objects void dtg->DeleteObject (HGDIOBJ *hObj); deletes a GDI graphics object(brush, font, ...) and sets NULL on the handle, if the handle is not NULL. Type-casting (HGDIOBJ*) on a specific object's handle pointer is needed as the argument to avoid warninings in the compile-stage of your compiler. void dtg->CreateBrush (DWTERMD_SolidBrush *sb); runs dtg->DeleteObject on the brush handle and creates a brush with the handle updated. void dtg->CreateFont (DWTERMD_Font *font); runs dtg->DeleteObject on the font handle and creates a font with the handle updated. ------------- Painting void dtg->PaintDot (HDC hDC, int x, int y, int dx, int dy, HBRUSH hBr); paints with the brush unless it's handle is NULL, all over the rectangular area in the DC of width dx and height dy with (x, y) the top left corner coordinates. ------------- on dWin and Canvases void dtg->DeleteCanvas (DWTERMD_Canvas *cv); deletes the memory DC and the bitmap with NULLs set on their handles, if the handles are not NULLs. HWND dtg->GetDWin (void); returns the handle of the display window in the dwTerm main window. void dtg->CreateCanvas (DWTERMD_Canvas *cv); runs dtg->DeleteCanvas, creates the memory DC and the bitmap, and selects the bitmap into the memory DC. void dtg->RegisterCanvas (DWTERMD_Canvas *cv); registers the canvas on dWin, so that any area in dWin('s DC) will copy the corresponding area in the canvas('s memory DC) when the former needs to be updated(drawn), from now on. In other words, this function informs dWin of the pointer to the memory DC's handle. void dtg->CopyCanvas (DWTERMD_Canvas *cv, HBRUSH hBr); runs the followings steps. 1. "erases" over the canvas, i.e. paints all over the canvas (memory DC) with the brush, unless the brush handle is NULL. 2. finally, lets dWin copy the canvas right now, using InvalidateRect. void dtg->UnregisterCanvas (DWTERMD_Canvas *cv); unregisters the canvas off dWin. That is, dWin will not copy any canvas from now on any more. In other words, this function sets NULL on dWin's internal pointer to any memory DC's handle. ------------- Scroll & Dispaly void dtg->Scroll (DWTERMD_PrintCanvas *prc); runs the followings steps. 1. moves up the display rectangle and all above it, if it's bottom is below the canvas's bottom, until the bottom or the top meets the canvas's corresponding border. 2. finally, lets dWin copy now all above the moved rectangle. Now you are ready to draw on this moved area. void dtg->CopyShift (DWTERMD_PrintCanvas *prc); lets dWin copy the display area now and redefines the area by moving the rectangle down a distance equal to it's height. Note that this function and dtg->Scroll form the general recipe of scroll & display as follows. - Adjust the rectangle except the top border, to fit what you want to display. Then scroll it using dtg->Scroll. - Display your text or grahics on the rectangular display area. - Finally, run this function. dtg->Print does all these steps for a text string. void dtg->Print (DWTERMD_PrintCanvas *prc, char *str); runs the following steps, which satisfy the recipe of scroll & display stated in the description of dtg->CopyShift above. 1. calculates the display rectangle for the string (str) and scrolls the rectangle using dtg->Scroll. Calculating means modifying the bottom to fit the string, while the right border is kept unchanged. 2. erases all on the diaplay area with the brush unless the brush handle pointer or the handle is NULL, and displays the string. 3. runs dtg->CopyShift. The string is assumed to be NULL-terminated, and DrawText is used in the first step to calculate with DT_CALRECT | fmt and in the second step to display with fmt as the last argument.

      3. Handlers
        A handler is called by dwTerm on a specific event, if the handler is found in your DLL. Be sure to write and export the handler with the correct name and arguments. About the order of calling - All the handlers in the following "Start and End" category except dwTermH_End are called in that order, right after the DLL loaded. We call them collectively the "start" handlers, and the last one (dwTermH_Start) especially the "Start" handler. They are called in the dwTerm's internal routine for the message issued when the main window (and the childs) is created (not yet visible) before the display window receives the automatic first update-message (to make it visible), so that you don't have to let the window redrawn (by InvalidateRect for example) in those handlers. - The descriptions of the other handlers tell you when they are called. ------------- Start and End void dwTermH_FunctionGroup_Graphics (DWTERMF_Graphics *fg_g) informs you of the pointer to the dwTerm Graphics function-group. All the functions listed above in this reference belong to this group, and can be called only using the group pointer, for example, as in fg_g->Print(&prc, "test"). You may save it on a global variable (named "dtg" as in samples and in this manual, or any other name) unless you will use the functions only in this handler. char *dwTermH_Start (char *CmdLine, char **Title) lets you initialize your work (for example, allocate memory spaces and so on). In this handler you can also process the followings. The first argument lets you use the dwTerm start-up command-line string. If you execute dwTerm by "dwTerm.exe myfile my commands" in a dos window or in a batch file for example, CmdLine points to the string "my commands" with a NULL character added. "myfile" is just a placeholder of a script file or a DLL with the path. The second argument is used to display your own title on the dwTerm title bar. You should let *Title point to a global space that contains a NULL-terminated string, "mytitle" for example, if you want dwTerm to write the title "dwTerm - mytitle" instead of "dwTerm". Otherwise, let *Title be NULL or do not touch it. To show a message on the dwTerm status bar, you should return a pointer to a global space that contains a NULL-terminated string. If the space has "my message" for example, the status bar reads "d0: my message". Otherwise, return NULL. The global spaces for the title and the return-message are used by dwTerm only once right after the handler returns, to write on the bars. Therefore you can use the spaces for other purposes or free them, in any handler called after this. BOOL dwTermH_End (void) lets you do something just before the DLL is unloaded. Return FALSE if you refuse to unload for some reason (you may want the user to wait until somthing is processed or to input something for example). Then dwTerm cancels unloading (Therefore it is kind of you to show the reason of refusal to the user before returning FALSE, using the Win32 MessageBox function for example). In general you may created a memory space or aquired other system resources in start handlers for example, and you may need to free them in this handler. ------------- Inputs char *dwTermH_Command (int nToken, char **Token) lets you process user's command entered by the input command window (the edit box in the dwTerm main window). dwTerm breaks the command string into a number of tokens where a token is a string without any blank, and adds a NULL to each token. The number is contained in nToken, and the token-array is pointed by Token, that is, the null-terminated tokens are pointed by Token[0] to Token[nToken-1] if any. For example, if the user entered "mycommand op1 op2", you have nToken=3, Token[0]="mycommand", Token[1]="op1", and Token[2]="op2". This handler has the same return-message feature on the dwTerm status bar, as that introduced in the last paragraph of the Start handler's description above, except that "d8" is used instead of "d0" if the command input is the 8th one.

  5. Limits of Trial Version

    The following paragraphs list the trial version's limits. They will disappear if you install a full license key.

    Only the first 20 commands in a script file are run and the others are ignored.

    The trial version also has a small additional area in the main window to display advertising pictures. If the computer is connected to the internet, new pictures may be displayed.

  6. License Agreement

    dwTerm is Copyright(C) 2008 http://www.softbattery.net.

    dwTerm consists of the trial version and the full license key.

    The compressed form of the trial version, which is a file with "zip" extension and in which this file (manual.htm) is contained as one of the components, can be freely copied and distributed as far as it is not modified.

    A copy of the compressed form of the trial version can be freely extracted into the component files and folders. All the files in the component folders except the "include" folder, and defad.txt can be freely copyied, modified or distributed. Any component else is NOT permitted to be de-assembled, de-compiled, reverse-engineered, modified, copied or distributed.

    A full license key is a file needed to upgrade the trial license to the full license, that is, to eliminate restrictions of the trial version's functions. A key is NOT permitted to be copied or distributed to be used in more than one computer, and is NOT permitted to be reverse-engineered, or modified.

    dwTerm is provided as is, without warranties of any kind. The copyright holder shall NOT be liable for damages of any kind.