----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
This text file contains four source files.  Use your editor to
cut this file into these:

          lc_samp.c
          lc_samp.h
          lc_samp.mak
          lc_samp.rc
    
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
------------------  HERE BEGINS THE LC_SAMP.C FILE -------------
/*  
    Sample Non-DDE client program for LC.EXE
    Garry J. Vass [72307,3311]
    
    This program (cloned from generic.c) uses the LC.EXE
    Winapp to perform calculations on strings containing
    expressions of the form:
    
         3+4+5+6
         3*4
         3/sin(3)*log(2)
         and so on.
         
    For locating code that is specific to this application
    (i.e., not generic), set your Search function for "COMMENT".
    
    Why not DDE?  
    
        1.  This particular client-server relationship
            is straightforward, well structured, 
            predictable, and requires expedience.
        2.  About 12 lines of code for this versus
            300+ lines to implement DDE.
        3.  The downside is that the messages WM_USER+63
            (request), and WM_USER+64 (reply) are
            looked upon as private channels.  This is
            conceptually similar to the old-world situation
            where DOS resident programs argued over who
            owned what hotkey (sigh).  I use a recognition
            signature 0x4C43, 'L'<<4 + 'C', in the message
            to establish ownership.


                                                              */    
/**************************************************************/
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/**************************************************************/
#include "windows.h"
#include "lc_samp.h"
int request_calculation( HWND sender, char *str );
/**************************************************************/
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/**************************************************************/
HANDLE hInst;
FARPROC Lproc;
char Inputstring[ 255 ] = "2+2";
char Resultstring[ 255 ] = "Result: 4";
char Anystring[ 255 ];
#define WAK( a ) MessageBox(  GetFocus(  ), a, "WIN-ACK", MB_OK  );
/**************************************************************/
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/**************************************************************/
/*  COMMENT:
    This variable is used to specify the handle (HWND) of
    the LC application.
*/
static HWND Lchwnd = -1;
/**************************************************************/
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/**************************************************************/
int PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
MSG msg;
    if( !hPrevInstance ) {
        if( !InitApplication( hInstance ) )
            return( FALSE );
        /*  COMMENT:
            This code starts the LC application.  If Windows
            cannot start the program, she returns a value
            less than 32.  
        */
        if( WinExec( "LC", SW_SHOWMINNOACTIVE ) < 32 ) {
            MessageBox( GetFocus(), 
                        (LPSTR)"I cannot find my server",
                        (LPSTR)"ShowStopper", 
                        MB_OK );
            return( FALSE );
        }
    }
    if( !InitInstance( hInstance, nCmdShow ) )
        return( FALSE );
    while( GetMessage( &msg, NULL, NULL, NULL ) ) {
           TranslateMessage( &msg );
           DispatchMessage( &msg );
    }
    return( msg.wParam );
}
/**************************************************************/
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/**************************************************************/
BOOL InitApplication( HANDLE hInstance )
{
WNDCLASS wc;
     wc.style              = NULL;
     wc.lpfnWndProc        = MainWndProc;
     wc.cbClsExtra         = 0;
     wc.cbWndExtra         = 0;
     wc.hInstance          = hInstance;
     wc.hIcon              = LoadIcon( NULL, IDI_APPLICATION );
     wc.hCursor            = LoadCursor( NULL, IDC_ARROW );
     wc.hbrBackground      = GetStockObject( WHITE_BRUSH );
     wc.lpszMenuName       = "lcmenu";
     wc.lpszClassName      = "lcclass";
     return( RegisterClass( &wc ) );
}
/**************************************************************/
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/**************************************************************/
BOOL InitInstance( HANDLE hInstance, int nCmdShow )
{
HWND hWnd;
     hInst = hInstance;
     hWnd = CreateWindow( "lcclass",
                          "LC Sample",
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT,
                          CW_USEDEFAULT,
                          CW_USEDEFAULT,
                          CW_USEDEFAULT,
                          NULL,
                          NULL,
                          hInstance,
                          NULL );
     if( !hWnd )
         return( FALSE );
     ShowWindow( hWnd, nCmdShow );
     UpdateWindow( hWnd );
     return( TRUE );
}
/**************************************************************/
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/**************************************************************/
long FAR PASCAL MainWndProc( HWND hWnd, unsigned message, WORD wParam, LONG lParam )
{
    switch( message ) {
            case WM_COMMAND:
                 if( wParam == IDM_ABOUT ) {
                     Lproc = MakeProcInstance( About, hInst );
                     DialogBox( hInst, "AboutBox", hWnd, Lproc );
                     FreeProcInstance( Lproc );
                     break;
                 } else if( wParam == IDM_ABOUT+1 ) {
                     /* COMMENT:
                        This code opens the dialog box for
                        entering expressions.
                     */
                     Lproc = MakeProcInstance( Samp, hInst );
                     DialogBox( hInst, "LCSAMP", hWnd, Lproc );
                     FreeProcInstance( Lproc );
                     break;
                 } else
                     return( DefWindowProc( hWnd, message, wParam, lParam ) );
            case WM_DESTROY:
                 PostQuitMessage( 0 );
                 break;
            default:
                 return( DefWindowProc( hWnd, message, wParam, lParam ) );
    }
    return( NULL );
}
/**************************************************************/
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/**************************************************************/
BOOL FAR PASCAL About( HWND hDlg, unsigned message, WORD wParam, LONG lParam )
{
    switch( message ) {
            case WM_INITDIALOG:
                 return( TRUE );
            case WM_COMMAND:
                 if( wParam == IDOK || wParam == IDCANCEL ) {
                     EndDialog( hDlg, TRUE );
                     return( TRUE );
                 }
                 break;
    }
    return( FALSE );
}
/**************************************************************/
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/**************************************************************/
BOOL FAR PASCAL Samp( HWND hDlg, unsigned message, WORD wParam, LONG lParam )
{
static int grab;

    switch( message ) {
            case WM_INITDIALOG:
                 SetDlgItemText( hDlg, 101, (LPSTR)Inputstring );
                 return( TRUE );
            case WM_COMMAND:
                 if( wParam == 100 ) {
                     EndDialog( hDlg, TRUE );
                     return( TRUE );
                 } else if( wParam == 107 ) { /* calc button */
                     /*  COMMENT:
                         When the calculate button has been pressed,
                         this code acquires the string and prepares
                         it for calculation.
                     */
                     GetDlgItemText( hDlg, 101, (LPSTR)Inputstring, 50 );
                     request_calculation( hDlg, Inputstring );
                 }
                 break;
            case WM_USER+64:
                 /*  COMMENT:
                     LC.EXE sends its results with the WM_USER+64
                     message.  The format it uses is
                             message:   WM_USER+64
                             wParam:    The handle (HWND) to LC's window.
                             lParam:    The low word contains a global
                                        atom with LC's result.
                                        The high word contains the
                                        handle (HWND) of the application
                                        that requested the service.
                     The processing does not need to take place
                     within a dialog callback, the reply message
                     is sent to whatever handle requested the service.
                 */
                 if( HIWORD( lParam ) == hDlg ) {/*Is it ours?*/
                     GlobalGetAtomName( LOWORD( lParam ), Anystring, 100 );
                     SetDlgItemText( hDlg, 103, (LPSTR)Anystring );
                     Lchwnd = (HWND)wParam;
                 }
                 break;
    }
    return( FALSE );
}
/**************************************************************/
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/**************************************************************/
int request_calculation( HWND sender, char *str )
{
ATOM anyatom;
     /*  COMMENT:
         This code prepares a string for calculation and sends
         it to the server.  LC listens for WM_USER+63 messages
         in the following format:
         
             message:  WM_USER+63
             wParam:   The handle (HWND) of the sending,
                       or client, window.
             lParam:   The low word contains a global atom
                       with the string to be calculated.
                       The high word contains a recognition 
                       signature, 0x4C43.
     */
     anyatom = GlobalAddAtom( (LPSTR) str );
     SendMessage( Lchwnd, WM_USER+63, sender, MAKELONG( anyatom, 0x4C43 ) );
     GlobalDeleteAtom( anyatom );
}
/**************************************************************/
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/*                                                            */
/**************************************************************/
---------------------  HERE ENDS THE LC_SAMP.C FILE  -----------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------



----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
---------------------  HERE BEGINS THE LC_SAMP MAKE FILE  ------
all: lc_samp.exe

lc_samp.res: lc_samp.rc lc_samp.h
    rc -r lc_samp.rc

lc_samp.obj: lc_samp.c lc_samp.h
	erase lc_samp.exe
    cl -c -AS -Gsw -Oas -Zpe lc_samp.c

lc_samp.exe: lc_samp.obj lc_samp.def
    link /NOD lc_samp,,, libw slibcew, lc_samp.def
    rc lc_samp.res

lc_samp.exe: lc_samp.res
    rc lc_samp.res
-----------------------  HERE ENDS THE LC_SAMP MAKE FILE -------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------


----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
---------------------  HERE BEGINS THE LC_SAMP.H FILE ----------
#define IDM_ABOUT 100
int PASCAL WinMain(HANDLE, HANDLE, LPSTR, int);
BOOL InitApplication(HANDLE);
BOOL InitInstance(HANDLE, int);
long FAR PASCAL MainWndProc(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL About(HWND, unsigned, WORD, LONG);
BOOL FAR PASCAL Samp(HWND, unsigned, WORD, LONG);
-----------------------  HERE ENDS THE LC_SAMP.H FILE ----------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------


----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------------------------------------------------
----------------------  HERE BEGINS THE LC_SAMP.RC FILE --------
#include "windows.h"
#include "lc_samp.h"

lcmenu MENU
BEGIN
    POPUP "About"
    BEGIN
        MENUITEM "&About...", IDM_ABOUT
    END
    MENUITEM  "&Calculate", IDM_ABOUT+1
END

LCSAMP DIALOG LOADONCALL MOVEABLE DISCARDABLE 11, 29, 258, 148
CAPTION "LC-Sample"
STYLE WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_SIZEBOX | WS_POPUP
BEGIN
    CONTROL "", 101, "edit", ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD, 140, 20, 70, 20
    CONTROL "Press here to calculate", 107, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 140, 50, 90, 20
    CONTROL "Done", 100, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 200, 130, 36, 14
    CONTROL "Enter an expression here", 102, "static", SS_LEFT | WS_CHILD, 40, 20, 90, 10
    CONTROL "Result:", 103, "static", SS_LEFT | WS_CHILD, 140, 80, 110, 10
    CONTROL "Samples", 104, "static", SS_LEFT | WS_CHILD, 10, 40, 30, 10
    CONTROL "3+4/(5+6)*(7*8)", 105, "static", SS_LEFT | WS_CHILD, 10, 60, 50, 10
    CONTROL "2*sin(3)^3*sqr(7)", 106, "static", SS_LEFT | WS_CHILD, 10, 70, 60, 10
END



AboutBox DIALOG 22, 17, 144, 75
STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "About"
BEGIN
    CTEXT "Sample LC-Client" -1, 0, 5, 144, 8
    DEFPUSHBUTTON "OK" IDOK, 53, 59, 32, 14, WS_GROUP
END
-----------------------  HERE ENDS THE LC_SAMP.RC FILE --------
---------------------------------------------------------------
---------------------------------------------------------------
---------------------------------------------------------------
---------------------------------------------------------------
---------------------------------------------------------------



