>> Rodney Roberts IS & Education Professional Homepage   >> Programming Tutorials And Downloads

Science makes it known,
Engineering makes it work,
Art makes it beautiful.


D Windows program calling Numerical Recipes: The Art of Scientific Computing1
Silverfrost Fortran 95 subroutines (Statistics Analysis); D downloads

This is a Windows version of D Programming Language, Silverfrost Fortran 95, and Numerical Recipes (which was a
command line implementation).  It uses the same sttstcs.dll (which is also used in Combining Fujitsu COBOL 3.0, PowerCOBOL 3.0, Silverfrost FTN95, and Numerical Recipes: The Art of Scientific Computing).  It was written while
learning D Windows programming using Win32 API calls.  It also uses a user-written D .dll, hedtio.dll (module hedtio).

To summarize, it is a Windows program written in D calling FORTRAN statistical analysis (avg, std dev, etc.) subroutines.

The D Windows programs were developed on an AMD Athlon II running WinXP Pro SP3 using DMD v2.066.0 (D2) and
are available for download (due to possible IP concerns, neither sttstcs.dll or its entire source code available for download;
see Numerical Recipes for more information about these scientific computing programs).  While the Windows main
program could use some refining, it is commented and should prove helpful in learning Win32 API programming.

    (Notepad++ was used to create/edit the .d and .di files - the tabbing and spacing may be off in MS Notepad)
  1. winstat.d - Windows main program calling statistical analysis subprograms; GetMessageA(&msg, null, 0, 0)
    loop contains processing for WM_RBUTTONUP (via call to hEditPopUpMenu (..) in module hedtio) and VK_TAB (via call to validTabMsg (...) in module hedtio);

    includes procedures to write / read statistical data as an ASCII comma separated values file; processes the command line argument as a file name to be opened (allows user in Windows Explorer to right-click on a file name and have winstat open it)
    right click file open

  2. module hedtio.d - general purpose subprograms for Windows Edit Controls I/O; Keyboard Interface for a Standard
    Scroll Bar;  right click short cut popup menu for basic clipboard Cut, Copy, Paste, Delete, Select All operations2,
    array Insert and Delete element (partial Undo functionality tested);  creating Edit Control Tool Tips;
    miscellaneous debugging procedures (displaying variables using MessageBoxA(...)), etc.;  includes DllMain(...),
    can be used in other Windows D applications.

    F.Y.I, module hedtio procedure hEditInitMsg(...) is callable from a Free Pascal Windows program using its
    D mangled name3 (hEditInitMsg is a simple procedure to set a Child Window's font to DEFAULT_GUI_FONT).
    Use Dependency Walker to get its mangled name (open either a D executable calling hEditInitMsg(...) or
    hedtio.dll itself, look in Export Function List View for a function name containing hEditInitMsg - in this case it was
    D6hedtio12hEditInitMsgFNbPvZv). In the Pascal program, declare D6hedtio12hEditInitMsgFNbPvZv (...) as an
    external function, with correct arguments:
    D mangled procedure name

    hedtio.di4 - hedtio.d d interface file, can be used by DMD when compiling winstat.d (instead of using hedtio.d for the module definition), this way can distribute the module .dll and .lib without distributing its source code, was initially created by using the DMD -H switch, then stripped out extraneous material so could get clean winstat.d compile (not used for calls from a Free Pascal program);
    hedtio.dll5 - hedtio.d dynamic link library;
    hedtio.lib - hedtio.dll import library (not used for calls from a Free Pascal program);
    chedtio.bat - batch file to compile hedtio.d;
    right click short-cut pop-up menu

    (module hedtio also contains useful const ints, structs, aliases, and global variable definitions; it is continuously
    tested, refined, and enhanced; check often for updates)

  3. sttstcs.for - Numerical Recipes FORTRAN Statistical Descriptions of Data subprograms [IMDIAN1(...),
    IMOMENT(...), IMODE(...), CRANK(...), GEOMEAN(...), and HARMONICMEAN(...)]; entire source code unavailable
    for download from this site; Older Numerical Recipes book editions available from the publisher with the original
    FORTRAN source code;
    sttstcs.dll - sttstcs.for dynamic link library;
    sttstcs.lib - sttstcs.dll import library;

User Interface with pop-up menu

Up to 300 data points are inputted in a grid of 30 rows and 10 columns, using an HWND array (HWND[300] hEditDataPt)
of edit text boxes.  The Number of Points edit box controls how many data points edit boxes are enabled for user input.

In the case WM_COMMAND: section, used if (HIWORD(wParam)==EN_KILLFOCUS) and a for loop to search for an
element of const uint[300] IDC_EDIT_DP equal LOWORD(wParam), indicating the user entered a value for one of the
data points.6

An extern (...) {...} declaration with a linkage attribute is needed since IMDIAN1(...), IMOMENT(...), IMODE(...), CRANK(...),
GEOMEAN(...)7, and HARMONICMEAN(...)7 are defined in another object file; it does not need a D interface (.di) file.
FORTRAN converts the identifiers in its symbol table to upper case, therefore the subroutine names must be in upper case.
// sttstcs.dll subroutine declarations
extern (Pascal)
  void* IMDIAN1(ref short, ref short, ref short, ref short[300]);
  void* IMOMENT(ref short, ref float, ref float, ref float, ref float, ref float, ref float, ref short, ref short[300]);
  void* IMODE(ref short, ref short, ref short, ref short, ref short, ref short[300]);
  void* CRANK(ref short, ref float, ref short[300], ref short[300], ref short);
  float GEOMEAN (ref short, ref short[300]);
  float HARMONICMEAN (ref short, ref short[300]);
extern (Pascal) {...} is the only extern declaration that produced a clean compile, requiring the parameters be passed to
the external sttstcs.dll subprograms in reverse order as defined in the FORTRAN subroutines declarations.

The subroutine calls require a try {} catch {} block in the windows program.8
try					  // Sort data, determine Median value
catch (Throwable e)
	MessageBoxA(hWnd, "IMDIAN1 Throw Error", "Statistical Analysis", MB_ICONERROR);
User Interface with results

When the user clicks on File, Calculate, the subprograms IMDIAN1(...), IMOMENT(...), IMODE(...), CRANK(...),
GEOMEAN(...), and HARMONICMEAN(...) are called and calculate Average, Median, Std Deviation, etc., which are then
displayed by winstat.
The data points are redisplayed in sorted order - IMDIAN1(...) calls internal subroutine ISORT(...) to sort the data point array.

  1. Create, compile, and link the FORTRAN file.
  2. Prepare the sttstcs.lib import library using implib (if you have not already done so); the SilverFrost generated sttstcs.lib
    is not compatible with the Digital Mars D compiler/linker.
    implib sttstcs.lib sttstcs.dll
  3. Need a simple dll.def
    LIBRARY         HEDTIO
    DESCRIPTION     'My DLL written in D'
  4. Compile and link hedtio.d into hedtio.dll:
    dmd -c hedtio.d -g -H
    dmd hedtio.obj dll.def -g -map
    implib /noi /system hedtio.lib hedtio.dll

    The -H switch creates hedtio.di, it was necessary to strip it down to bare essentials in order to perform step 6.
  5. Need a simple win.def file
    (For WinXP, may want to use SUBSYSTEM WINDOWS, 4 for additional usability with wndclass.hbrBackground
    and "STATIC" HWND child windows)
  6. dmd winstat.d sttstcs.lib hedtio.lib win.def

    (unlike a .d .dll, there is not any need to explicitly include a DllMain routine in the FORTRAN .dll; the SilverFrost
    SLINK can generate a default LibMain, which serves a similar purpose)
(For interoperability with default SilverFrost Fortran 95 and Free Pascal, use the D2 32-bit Command Prompt)

1. Press, William H., Brian P. Flannery, Saul A Teukolsky, and William T. Vetterling (1986). Numerical
Recipes: The Art of Scientific Computing
. New York:Press Syndicate of the University of Cambridge.
2. Thanks to Simpledisplay.d for the clipboard code; module hedtio procedure hEditPopUpMenu (...)
uses the Win32 API procedures CreatePopupMenu(), AppendMenuA(...), TrackPopupMenu(...),
and DestroyMenu (...) for the short cut menu processing; the clipboard operations consist of
Win32 API calls to OpenClipboard(hWnd), IsClipboardFormatAvailable(CF_TEXT),
GetClipboardData (...), GlobalAlloc (GMEM_MOVEABLE, ...), GlobalLock(...),
EmptyClipboard( ), SetClipboardData (CF_TEXT, ...), and GlobalUnlock(...)This is a rudimentary
implementation of Win32 API clipboard operations designed for an application using an array of
child window edit controls containing numeric data (hence the need for Delete Element and
Insert Element options in the pop-up menu, hEditPopUpMenu (...) verifying the clipboard data
is numeric).
  hEditPopUpMenu (...) needs minor work.  As it is being tweaked, old code is
"commented out" prior to revising.  This way, it is easy to revert back to a previous state.  Current issue
is partially selecting an edit control array element, extracting a subset of its data, and pasting to another
edit control - SELECT ALL does not work again until use mouse to select all text.
  Time permitting,
will continue researching D documentation and Win32 Developer's References for solution.
hEditPopUpMenu (...) is callable from Object Pascal via module hedtio's cPopUpMenu (...).
3. Only try this method to avoid making changes to the D module.  As an alternative, write a D procedure
declared extern (C) which calls the desired D procedure; the Pascal procedure then calls the D
"wrapper" procedure.  See cPopUpMenu (...) for an example.
4. For additional information on *.di files, see D .dll Calling FORTRAN .dll.
5. Additional information on writing D DLLs can be found at Win32 DLLs in D.
6. EN_KILLFOCUS does not get set until after the user clicks (or TABs) out of the field.
7. Recently added. These come from FORTRAN For Scientists & Engineers, 2nd Edition, 1995
8. Considered eliminating the try {} catch {} block by appending nothrow to each subprogram
declaration.  However, a misbehaving subroutine was generating floating point errors and was caught
upon exit by the try {} catch {} block.  In a computationally intense application, it may be
advantageous to declare a subprogram nothrow, eliminating the overhead of try {} catch {} processing.

Any and all © copyrights, ® ™ trademarks, or other intellectual property (IP) mentioned here are the property of their respective owners.

Feel free to use any of the above in your project (without violating any intellectual property rights); please give credit (same idea as Copyleft).

Page best viewed with Mozilla FireFox 3.6.13 (or higher) and Google Chrome Version 40.0.2214.94 (or higher) - Internet Explorer may not display or link correctly.

Free web hosting provided by  
Award Space Web Hosting 50 Webs Hosting Free Web Hosting. Free Web Hosting. , &  GigaRocket Web Hosting

>> Rodney Roberts IS & Education Professional Homepage   >> Programming Tutorials And Downloads