
//***************************************************
// Generalised Bitmap Module C++ adapter for GBM plugins
//
// Requires: GBM.DLL version 1.35 or higher (with multipage support)
//
// Copyright (C) 2006-2008 Heiko Nitzsche
//
//   This software is provided 'as-is', without any express or implied
//   warranty.  In no event will the author be held liable for any damages
//   arising from the use of this software.
//
//   Permission is granted to anyone to use this software for any purpose,
//   including commercial applications, and to alter it and redistribute it
//   freely, subject to the following restrictions:
//
//   1. The origin of this software must not be misrepresented; you must not
//      claim that you wrote the original software. If you use this software
//      in a product, an acknowledgment in the product documentation would be
//      appreciated but is not required.
//   2. Altered source versions must be plainly marked as such, and must not be
//      misrepresented as being the original software.
//   3. This notice may not be removed or altered from any source distribution.
//
//***************************************************

#ifdef __IBMCPP__
  #pragma strings( readonly )
#endif

#include "os2defs.h"
#include <string.h>
#include "GbmDialogAccessor.hpp"

// ---------------------------------------------------------

GbmDialogAccessor::GbmDialogAccessor() throw (GbmDialogAccessorException)
    : moduleName(NULL),
      moduleHandle(NULLHANDLE)
{
    // load GBMDLG.DLL via LIBPATH lookup

    if (! init("GBMDLG"))
    {
        throw GbmDialogAccessorException();
    }
}

// ---------------------------------------------------------

GbmDialogAccessor::GbmDialogAccessor(const char * dllPath) throw (GbmDialogAccessorException)
    : moduleName(NULL),
      moduleHandle(NULLHANDLE)
{
    // load GBM.DLL via absolute path

    if (! init(dllPath))
    {
        throw GbmDialogAccessorException();
    }
}

// ---------------------------------------------------------

GbmDialogAccessor::~GbmDialogAccessor()
{
    delete [] moduleName;
    moduleName = NULL;

    if (moduleHandle != NULLHANDLE)
    {
        DosFreeModule(moduleHandle);
        moduleHandle = NULLHANDLE;
    }
}

// ---------------------------------------------------------

const char * GbmDialogAccessor::getModuleName() const
{
    return moduleName;
}

// ---------------------------------------------------------

const char * GbmDialogAccessor::getHelpFileName() const
{
    return "GBMDLG.HLP";
}

// ---------------------------------------------------------

BOOLEAN GbmDialogAccessor::init(const char * dllPath)
{
    if (dllPath == NULL)
    {
        return FALSE;
    }

    // load GBM.DLL
    UCHAR  loadError[201] = "";
    APIRET rc             = 0;

    // Load GBMDLG.DLL

    rc = DosLoadModule((PSZ)loadError,
                       sizeof(loadError)-1,
                       (PSZ)dllPath,
                       &moduleHandle);

    if (rc == 0)
    {
        const int moduleNameLength = strlen(dllPath);
        moduleName = new char[moduleNameLength+1];
        strcpy(moduleName, dllPath);

        /* as _System exported functions */
        rc = DosQueryProcAddr(moduleHandle, 0L, "GbmFileDlg", (PFN *) &fn_GbmFileDlg);
        if (rc)
        {
            delete [] moduleName;
            moduleName = NULL;
            DosFreeModule(moduleHandle);
            moduleHandle = NULLHANDLE;
            return FALSE;
        }

        // the dialog window procedure is optional, so don't throw an error
        rc = DosQueryProcAddr(moduleHandle, 0L, "GbmDefFileDlgProc", (PFN *) &fn_GbmDefFileDlgProc);
        if (rc)
        {
            fn_GbmDefFileDlgProc = NULL;
        }
        return TRUE;
    }
    moduleHandle = NULLHANDLE;
    return FALSE;
}

// ---------------------------------------------------------

GBM_ERR GbmDialogAccessor::GbmFileDlg(HWND hwndP, HWND hwndO, GBMFILEDLG *pgbmfild) const
{
    return fn_GbmFileDlg(hwndP, hwndO, pgbmfild);
}

// ---------------------------------------------------------

BOOL GbmDialogAccessor::hasPublicGbmDefFileDlgProc() const
{
    return (fn_GbmDefFileDlgProc != NULL) ? TRUE : FALSE;
}

MRESULT GbmDialogAccessor::GbmDefFileDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) const
{
    if (fn_GbmDefFileDlgProc != NULL)
    {
        return fn_GbmDefFileDlgProc(hwnd, msg, mp1, mp2);
    }
    return NULL;
}


