/*************************************************************
File: DllUser.c
Purpose: Holds all the code for the DllUser sample application

Author: Russell "FattyMcGee" Morris

Copyright(c) Inside3D 1997
*************************************************************/

#include <windows.h>
#include "dlluser.h"
#include "basicdll.h"
#include "dlluser.rh"

HINSTANCE g_hInst;      // the current instance

//
//  FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
//
//  PURPOSE: Entry point for the application.
//
//  COMMENTS:
//
// This function initializes the application and processes the
// message loop.
//
#pragma argsused
int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow )
{

    MSG msg;

    if (!InitApplication(hInstance))
            return (FALSE);

    // Create the main window.
    if (!InitInstance(hInstance, nCmdShow))
        return (FALSE);

   // Acquire and dispatch messages until a WM_QUIT message is received.
    while (GetMessage(&msg,NULL,0,0))
        {
            TranslateMessage(&msg);    // Translates virtual key codes.
            DispatchMessage(&msg);     // Dispatches message to window.
        }
    return (msg.wParam);           // Returns the value from PostQuitMessage.

}

//
//  FUNCTION: InitApplication(HANDLE)
//
//  PURPOSE: Initializes window data and registers window class
//
//  COMMENTS:
//
//    In this function, we initialize a window class by filling out a data
//    structure of type WNDCLASS and calling the Windows RegisterClass()
//    function.
//
BOOL InitApplication(HANDLE hInstance)
{
    WNDCLASS  wc;

    // Register the window class for my window.                                                           */
    wc.style = 0;                       // Class style.
    wc.lpfnWndProc = (WNDPROC)MainWndProc; // Window procedure for this class.
    wc.cbClsExtra = 0;                  // No per-class extra data.
    wc.cbWndExtra = 0;                  // No per-window extra data.
    wc.hInstance = hInstance;           // Application that owns the class.
    wc.hIcon = 0;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName = "Menu"  ;   // Name of menu resource in .RC file.
    wc.lpszClassName = "DllUserWClass"// Name used in call to CreateWindow.

    return (RegisterClass(&wc));
}

//
//   FUNCTION: InitInstance(HANDLE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance( HANDLE hInstance, int nCmdShow)
{
    HWND            hWnd;

   // Save off the handle to the current instance.
    g_hInst = hInstance;

    // Create a main window for this application instance.
    hWnd = CreateWindow(
        "DllUserWClass" ,
        "DllUser sample application" ,
        WS_OVERLAPPEDWINDOW,            // Window style.
        CW_USEDEFAULT,                  // Default horizontal position.
        CW_USEDEFAULT,                  // Default vertical position.
        CW_USEDEFAULT,                  // Default width.
        CW_USEDEFAULT,                  // Default height.
        NULL,                           // Overlapped windows have no parent.
        NULL,                           // Use the window class menu.
        g_hInst,                        // This instance owns this window.
        NULL                            // Pointer not needed.
    );

    // If window could not be created, return "failure".
    if (!hWnd)
        return (FALSE);

    // Make the window visible; update its client area; and return "success".
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    return (TRUE);

}

//
//  FUNCTION: MainWndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the main window.
//
//  MESSAGES:
//
// WM_CREATE - initialize window and create the MLE
// WM_COMMAND - process the application menu
// WM_SIZE - size the MLE in the main window
// WM_DESTROY - post a quit message and return
//
//
LONG APIENTRY MainWndProc( HWND hWnd, UINT message, UINT wParam, LONG lParam)
{
  HMODULE hDll;
  LPFNEXPORTED funcPtr;

    switch (message) {

        case WM_COMMAND:           // message: command from application menu
            switch ( LOWORD( wParam ))
            {
                case CM_USENORMAL:

                    // We linked to the function at compile time,
                    // so let's just call it
                    //
                    ExportedFunction();

                    break ;

                case CM_USEFP:
                    // First let's load the DLL
                    //
                    hDll = LoadLibrary("basicdll.dll" );

                    // On error, we need to return
                    //
                    if ( !hDll )
                      return 0;

                    // Now let's get a pointer to ExportedFunction
                    //
                    funcPtr = (LPFNEXPORTED)
                               GetProcAddress( hDll, "ExportedFunction"  );

                    // If funcPtr is null, we need to return
                    //
                    if ( !funcPtr )
                      return 0;

                    // Now let's call ExportedFunction!  Notice how you
                    // use the name of the function pointer just like
                    // you would use the actual function name.
                    //
                    funcPtr();

                    // Now we're done with basicdll.dll, so let's unload
                    // it.
                    //
                    FreeLibrary( hDll );

                    break ;

                case CM_ABOUT:
                    MessageBox( hWnd, "DllUser Sample Application\r\n"
                                "Copyright(c) Inside3D 1997\r\n"
                                "Author: FattyMcGee\r\n"
                                "gt4336b@prism.gatech.edu" ,
                                "About this application" ,
                                MB_ICONINFORMATION | MB_OK );
                    break ;

                case CM_EXIT:
                    PostQuitMessage(0);
                    break ;

                default :
                    return (DefWindowProc(hWnd, message, wParam, lParam));

            }
            break ;

        case WM_DESTROY:                  // message: window being destroyed
            PostQuitMessage(0);
            break ;


        default :
            return (DefWindowProc(hWnd, message, wParam, lParam));
    }
    return (0);
}