///////////////////////////////////////////////////////////////////////////
//
//  NAME
//    mcdlg_dl.cpp - C/C+++ dynamic link file for Motion dialog package
//
//  DESCRIPTION
//    This file provides support for dynamically linking a C/C++
//    application to PMC's Motion Control Dialogs. 
//
//    To change your application from standard static linking (i.e. using
//    MCDLG32.LIB) to dynamic linking:
//
//      1. Include this file (MCDLG.CPP) in your project
//      2. Remove any reference to MCDLG32.LIB from your project
//      3. Replace the standard MCAPI header file (MCDLG.H) with the 
//         version that accompanied MCDLG.CPP
//      4. Add a call to MCLoadDialogs() prior to calling any Motion
//         Control Dialogs function
//
//  RELEASE HISTORY
//    Copyright (c) 2002-2014 by Precision Micro Control Corp. All rights
//    reserved.
//
//    $Id: mcdlg_dl.cpp 796 2013-04-20 00:35:12Z brian $
//
//    Version 3.2.0      4-Jan-02       Programmer: Brian Gaynor
//      - First release
//
//    Version 3.2.1     26-Apr-02       Programmer: Brian Gaynor
//      - No changes to this module
//
//    Version 3.3.0		15-Jan-03		Programmer: Brian Gaynor
//      - No changes to this module
//
//    Version 3.4.0		 2-Jun-03		Programmer: Brian Gaynor
//      - No changes to this module
//
//    Version 3.4.1		31-Oct-03		Programmer: Brian Gaynor
//      - No changes to this module
//
//    Version 3.4.2		 5-Jul-04		Programmer: Brian Gaynor
//      - No changes to this module
//
//    Version 3.5.0		19-Nov-04		Programmer: Brian Gaynor
//      - Renamed to mcdlg_dl.cpp so the dynamic linking code can more 
//        easily co-exist with the standard headers
//
//    Version 3.5.1		 1-Feb-05		Programmer: Brian Gaynor
//      - No changes to this module
//
//    Version 3.5.2		24-Feb-05		Programmer: Brian Gaynor
//      - No changes to this module
//
//    Version 4.0.0		16-Jan-06		Programmer: Brian Gaynor
//      - Converted long int types to int, doesn't effect 32-bit code,
//        sizeof(long int) == sizeof(int), but this will make sure that 
//        parameter sizes don't swell under 64-bit builds
//      - Added MCGetDigitalIOEx(), can return status of 32 digital I/O
//        channels in one call (BR #121).
//      - Wrapper functions for the platform specific dynamic function 
//        loading libraries are now used, enabling this code to work on 
//        Linux as well as Windows.
//
//    Version 4.0.1		27-Mar-06		Programmer: Brian Gaynor
//      - No changes to this module
//
//    Version 4.0.2		21-Apr-06		Programmer: Brian Gaynor
//      - No changes to this module
//
//    Version 4.0.3		17-Nov-06		Programmer: Brian Gaynor
//      - Removed include for stdafx.h (needed for precompiled headers). If
//        your app has precompiled headers enabled in Visual Studio simply
//        select this file from the Solution View and disable precompiled 
//        headers for this file.
//
//    Version 4.0.4		16-May-07		Programmer: Brian Gaynor
//      - No changes
//
//    Version 4.0.5		13-Jul-07		Programmer: Brian Gaynor
//      - No changes
//
//    Version 4.1.0		 1-Dec-08		Programmer: Brian Gaynor
//      - Changes to code that loads function pointers to quiet C4076 
//        warnings from Visual Studio (bug #100143).
//
//    Version 4.1.1		14-Jul-09		Programmer: Brian Gaynor
//      - No changes
//
//    Version 4.1.2		25-Sep-09		Programmer: Brian Gaynor
//      - No changes
//
//    Version 4.2.0		 1-Apr-10		Programmer: Brian Gaynor
//      - Paths for default INI files are now explicitly set (required
//        for them to work on Windows 7).
//
//    Version 4.3.0		19-Dec-12		Programmer: Brian Gaynor
//      - No changes
//
//    Version 4.3.1		XX-Apr-13		Programmer: Brian Gaynor
//      - DLL not found will now return MCERR_NOT_FOUND to differentiate
//        from missing functions which return MCERR_NOT_PRESENT. Missing
//        DLL usually means no API installed (application may want to run
//        in an offline mode), whereas missing functions usually mean the
//        version of the API installed is too old (bug #100201).
//
///////////////////////////////////////////////////////////////////////////

#include "stdafx.h"			// you may need to modify to match your project

//
//  Dialog Function pointer declarations
//
int       (APIENTRY* MCDLG_AboutBox)(HWND, LPCSTR, int);
int       (APIENTRY* MCDLG_ConfigureAxis)(HWND, HCTRLR, WORD, int, LPCSTR);
LPCSTR    (APIENTRY* MCDLG_ControllerDesc)(short int, LPSTR, int);
int       (APIENTRY* MCDLG_ControllerInfo)(HWND, HCTRLR, int, LPCSTR);
int       (APIENTRY* MCDLG_DownloadFile)(HWND, HCTRLR, int, LPCSTR);
int       (APIENTRY* MCDLG_Initialize)(void);
int       (APIENTRY* MCDLG_ListControllers)(short int[], short int);
LPCSTR    (APIENTRY* MCDLG_ModuleDesc)(short int, LPSTR, int);
int       (APIENTRY* MCDLG_RestoreAxis)(HCTRLR, WORD, int, LPCSTR);
int       (APIENTRY* MCDLG_RestoreDigitalIO)(HCTRLR, WORD, WORD, LPCSTR);
int       (APIENTRY* MCDLG_SaveAxis)(HCTRLR, WORD, int, LPCSTR);
int       (APIENTRY* MCDLG_SaveDigitalIO)(HCTRLR, WORD, WORD, LPCSTR);
int       (APIENTRY* MCDLG_Scaling)(HWND, HCTRLR, WORD, int, LPCSTR);
short int (APIENTRY* MCDLG_SelectController)(HWND, short int, int, LPCSTR);

#if (_MCDLG_VER >= 300)

LPCSTR    (APIENTRY* MCDLG_CommandFileExt)(int, int, LPSTR, int);
LPCSTR    (APIENTRY* MCDLG_ControllerDescEx)(int, int, LPSTR, int);
LPCSTR    (APIENTRY* MCDLG_ModuleDescEx)(int, int, LPSTR, int);

#endif

///////////////////////////////////////////////////////////////////////////
//
//  NAME
//    MCLoadDialogs - loads Motion Dialog function pointers
//
//  DESCRIPTION
//    Dynamically Loads functions from the Motion Dialogs DLL.
//
//  RETURNS
//    MCERR_NOERROR     - function pointers loaded okay
//    MCERR_NOT_PRESENT - function name not found
//
///////////////////////////////////////////////////////////////////////////
int MCLoadDialogs( void )
{
#ifdef _WIN32
	HINSTANCE hLib;
#else
	void* hLib;
#endif

    if (hLib = wl_dynloadopen(MCDLG_LIB)) 
	{
		if ((MCDLG_AboutBox = (int (APIENTRY*)(HWND, LPCSTR, int))wl_dynloadsym(hLib, "MCDLG_AboutBox")) == 0)
			return MCERR_NOT_PRESENT;
		if ((MCDLG_ConfigureAxis = (int (APIENTRY*)(HWND, HCTRLR, WORD, int, LPCSTR))wl_dynloadsym(hLib, "MCDLG_ConfigureAxis")) == 0)
			return MCERR_NOT_PRESENT;
		if ((MCDLG_ControllerDesc = (LPCSTR (APIENTRY*)(short, LPSTR, int))wl_dynloadsym(hLib, "MCDLG_ControllerDesc")) == 0)
			return MCERR_NOT_PRESENT;
		if ((MCDLG_ControllerInfo = (int (APIENTRY*)(HWND, HCTRLR, int, LPCSTR))wl_dynloadsym(hLib, "MCDLG_ControllerInfo")) == 0)
			return MCERR_NOT_PRESENT;
		if ((MCDLG_DownloadFile = (int (APIENTRY*)(HWND, HCTRLR, int, LPCSTR))wl_dynloadsym(hLib, "MCDLG_DownloadFile")) == 0)
			return MCERR_NOT_PRESENT;
		if ((MCDLG_Initialize = (int (APIENTRY*)(void))wl_dynloadsym(hLib, "MCDLG_Initialize")) == 0)
			return MCERR_NOT_PRESENT;
		if ((MCDLG_ListControllers = (int (APIENTRY*)(short[], short))wl_dynloadsym(hLib, "MCDLG_ListControllers")) == 0)
			return MCERR_NOT_PRESENT;
		if ((MCDLG_ModuleDesc = (LPCSTR (APIENTRY*)(short, LPSTR, int))wl_dynloadsym(hLib, "MCDLG_ModuleDesc")) == 0)
			return MCERR_NOT_PRESENT;
		if ((MCDLG_RestoreAxis = (int (APIENTRY*)(HCTRLR, WORD, int, LPCSTR))wl_dynloadsym(hLib, "MCDLG_RestoreAxis")) == 0)
			return MCERR_NOT_PRESENT;
		if ((MCDLG_RestoreDigitalIO = (int (APIENTRY*)(HCTRLR, WORD, WORD, LPCSTR))wl_dynloadsym(hLib, "MCDLG_RestoreDigitalIO")) == 0)
			return MCERR_NOT_PRESENT;
		if ((MCDLG_SaveAxis = (int (APIENTRY*)(HCTRLR, WORD, int, LPCSTR))wl_dynloadsym(hLib, "MCDLG_SaveAxis")) == 0)
			return MCERR_NOT_PRESENT;
		if ((MCDLG_SaveDigitalIO = (int (APIENTRY*)(HCTRLR, WORD, WORD, LPCSTR))wl_dynloadsym(hLib, "MCDLG_SaveDigitalIO")) == 0)
			return MCERR_NOT_PRESENT;
		if ((MCDLG_Scaling = (int (APIENTRY*)(HWND, HCTRLR, WORD, int, LPCSTR))wl_dynloadsym(hLib, "MCDLG_Scaling")) == 0)
			return MCERR_NOT_PRESENT;
		if ((MCDLG_SelectController = (short (APIENTRY*)(HWND, short, int, LPCSTR))wl_dynloadsym(hLib, "MCDLG_SelectController")) == 0)
			return MCERR_NOT_PRESENT;

#if (_MCDLG_VER >= 300)
		if ((MCDLG_CommandFileExt = (LPCSTR (APIENTRY*)(int, int, LPSTR, int))wl_dynloadsym(hLib, "MCDLG_CommandFileExt")) == 0)
			return MCERR_NOT_PRESENT;
		if ((MCDLG_ControllerDescEx = (LPCSTR (APIENTRY*)(int, int, LPSTR, int))wl_dynloadsym(hLib, "MCDLG_ControllerDescEx")) == 0)
			return MCERR_NOT_PRESENT;
		if ((MCDLG_ModuleDescEx = (LPCSTR (APIENTRY*)(int, int, LPSTR, int))wl_dynloadsym(hLib, "MCDLG_ModuleDescEx")) == 0)
			return MCERR_NOT_PRESENT;
#endif

	}
	else
		return MCERR_NOT_FOUND;
	
	return MCERR_NOERROR;
}
