On va faire autrement... Voilà MA conduite "générique", plus simple et commentée
CODE
#include "stdafx.h" // Include API standards
#include "syncmgr.h"
#include "condapi.h"
#include "basemon.h"
#include "condmgre.h"
#include "hslog.h"
#include "mycond.h" // Déclarations (pas grand chose)
#include "pdcmn.h"
#include "cmnres.h"
#include "mycondDlg.h" // Dialogue de configuration de la conduite
HINSTANCE myInst=0;
class CMyCondDll : public CWinApp
{
public:
virtual BOOL InitInstance(); // Initialization
virtual int ExitInstance(); // Termination
};
Rien d'extraordinaire dans les déclarations, n'est-ce pas ?
CODE
/////////////////////////////////////////////////////////////////////////////
//
// Function: InitInstance()
//
// Description: basic initialisation when DLL is loaded
//
// Parameters: none
//
// Returns: Success (non-zero) or Failure (zero)
//
/////////////////////////////////////////////////////////////////////////////
// REVISION HISTORY:
//
// 10/27/97 jayita initial version
//
/////////////////////////////////////////////////////////////////////////////
BOOL CMyCondDll::InitInstance()
{
// DLL initialization
myInst = AfxGetInstanceHandle();
// add any extension DLLs into CDynLinkLibrary chain
return TRUE;
}
Il s'agit simplement d'une initialisation standard de DLL
CODE
/////////////////////////////////////////////////////////////////////////////
//
// Function: ExitInstance()
//
// Description: DLL clean up before exit
//
// Parameters: none
//
// Returns: Error code
//
/////////////////////////////////////////////////////////////////////////////
// REVISION HISTORY:
//
// 10/27/97 jayita initial version
//
/////////////////////////////////////////////////////////////////////////////
int CMyCondDll::ExitInstance()
{
// DLL clean up, if required
return CWinApp::ExitInstance();
}
Et la fonction de fin d'instance...
CODE
/////////////////////////////////////////////////////////////////////////////
// The one and only CMaCondDll object
CMyCondDll myCondDll;
Et l'instanciation... Donc tout ce qui est ci-dessus n'est qu'un squelette standard de DLL, que tu peux remplacer par tout autre code standard (la version en C est tout aussi utilisable).
CODE
/////////////////////////////////////////////////////////////////////////////
// OpenConduit
/////////////////////////////////////////////////////////////////////////////
//
// Function: OpenConduit()
//
// Description: This is the main function which gets called by the hotsync
// application. The conduit acts upon the sync properties
// passed by the HotSync application. In this particular
// example only, copying hand-held to pc and vise versa are
// implemented. All other properties defaults to the same
// handler as eHHtoPC.
//
// Parameters: PROGRESSFN - pFn, Pointer to a callback function
// used to report progress.
// CSyncProperties& - rProps, reference to sync properties
//
// Returns: !0 if error
//
/////////////////////////////////////////////////////////////////////////////
ExportFunc long OpenConduit(PROGRESSFN pFn, CSyncProperties& rProps)
{
long retval = 0;
char data[4096];
char retdat[64];
CCallModuleParams params;
CONDHANDLE conduitHandle = (CONDHANDLE)0;
// Check if anything to do
if (rProps.m_SyncType == eDoNothing)
{
sprintf(data, "%s - Conduite réglée sur "Ne rien faire"", STR_MY_CONDUIT);
LogAddEntry(data, slSyncFinished, TRUE);
return (retval);
}
// Register this conduit with SyncMgrDLL for communication to HH
if (retval = SyncRegisterConduit(conduitHandle))
{
return (retval);
}
// Do the real work HERE
// End of processing
sprintf(data, "%s", STR_MY_CONDUIT);
LogAddEntry(data, slSyncFinished, TRUE);
// End of job: unregister with SyncMgrDLL
SyncUnRegisterConduit(conduitHandle);
return (retval);
}
Et c'est là l'essentiel : c'est cette fonction qui est appelée lorsque la conduite est exécutée... A toi de remplir avec ton traitement...
Note que le modifier ExportFunc est spécifique à VC++ mais qu'il revient à exporter la fonction (tout bêtement)...
CODE
/////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////
//
// Function: GetConduitName()
//
// Description: Extern "C" entry point into this conduit which returns
// the name to be used when display messages regarding
// this conduit.
//
// Parameters: pszName - buffer in which to place the name
// nLen - maximum number of bytes of buffer
//
// Returns: -1 indicates erros
//
/////////////////////////////////////////////////////////////////////////////
ExportFunc long GetConduitName(char* pszName,WORD nLen)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
long retval = 0;
memset(pszName, 0, nLen);
strncpy(pszName, STR_MY_CONDUIT, nLen-1);
return retval;
}
Utilisé pour afficher le nom de la conduite dans la liste de hotsync...
CODE
/////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////
//
// Function: GetConduitVersion()
//
// Description: Extern "C" entry point into this conduit which returns
// the conduits version
//
// Parameters: none
//
// Returns: DWORD indicating major and minor version number
// HIWORD - reserved
// HIBYTE(LOWORD) - major number
// LOBYTE(LOWORD) - minor number
//
/////////////////////////////////////////////////////////////////////////////
ExportFunc DWORD GetConduitVersion()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return MY_CONDUIT_VERSION;
}
Pour ta gestion de version
CODE
/////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////
//
// Method: GetConduitInfo
//
// Description: This function provides a way for a Conduit to provide info
// to the caller.
// In this version of the call, MFC Version, Conduit Name, and
// Default sync action are the types of information this call
// will return.
//
// Parameters: ConduitInfoEnum infoType - enum specifying what info is being
// requested.
// void *pInArgs - This parameter may be null, except for the Conduit
// name enum, this value will be a ConduitRequestInfoType structure.
// This following to parameters vary depending upon the info being requested.
// For enum eConduitName
// void *pOut - will be a pointer to a character buffer
// DWORD *pdwOutSize - will be a pointer to a DWORD specifying the size of the character buffer.
//
// For enum eMfcVersion
// void *pOut - will be a pointer to a DWORD
// DWORD *pdwOutSize - will be a pointer to a DWORD specifying the size of pOut.
//
// For enum eDefaultAction
// void *pOut - will be a pointer to a eSyncType variable
// DWORD *pdwOutSize - will be a pointer to a DWORD specifying the size of pOut.
//
// Returns: 0 - Success.
// !0 - error code.
//
/////////////////////////////////////////////////////////////////////////////
// REVISION HISTORY:
// 01/23/98 KRM Created
//
/////////////////////////////////////////////////////////////////////////////
ExportFunc long GetConduitInfo(ConduitInfoEnum infoType, void *pInArgs, void *pOut, DWORD *pdwOutSize)
{
if (!pOut)
{
return CONDERR_INVALID_PTR;
}
if (!pdwOutSize)
{
return CONDERR_INVALID_OUTSIZE_PTR;
}
switch (infoType)
{
case eConduitName:
memset((TCHAR *) pOut, 0, *pdwOutSize);
strncpy((TCHAR *) pOut, STR_MY_CONDUIT, (*pdwOutSize)-1);
break;
case eDefaultAction:
if (*pdwOutSize != sizeof(eSyncTypes))
{
return CONDERR_INVALID_BUFFER_SIZE;
}
(*(eSyncTypes*)pOut) = eFast;
break;
case eMfcVersion:
if (*pdwOutSize != sizeof(DWORD))
{
return CONDERR_INVALID_BUFFER_SIZE;
}
(*(DWORD*)pOut) = MFC_VERSION_50;
break;
default:
return CONDERR_UNSUPPORTED_CONDUITINFO_ENUM;
}
return 0;
}
Très important : c'est là où tu "déclares" ta conduite au programme hotsync : son nom (oui, encore, il y a plusieurs versions et l'action par défaut : synchroniser / Palm remplace PC / ...)
CODE
/////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////
//
// Function: ConfigureConduit
//
// Description: Extern "C" entry point into this conduit which returns
// should display the UI necessary to configure this
// conduit.
//
// Parameters: none
//
// Returns: 0 - success, !0 - failure
//
/////////////////////////////////////////////////////////////////////////////
// REVISION HISTORY:
// 05Oct96 cja created
/////////////////////////////////////////////////////////////////////////////
ExportFunc long ConfigureConduit(CSyncPreference& pref)
{
long nRtn = -1;
char szName[81];
CMCConfigureDlg actDlg;
pref.m_SyncPref = eNoPreference;
GetConduitName(szName,80);
actDlg.m_csGroupText = szName;
switch (pref.m_SyncType)
{
case eFast:
case eSlow:
actDlg.m_nActionIndex = 0;
break;
/* case ePCtoHH:
actDlg.m_nActionIndex = 1;
break;
case eHHtoPC:
actDlg.m_nActionIndex = 2;
break;*/
case eDoNothing:
default:
actDlg.m_nActionIndex = 1;
break;
}
if (actDlg.DoModal() == IDOK)
{
switch (actDlg.m_nActionIndex)
{
case 0:
pref.m_SyncType = eFast;
break;
case 1:
/* pref.m_SyncType = ePCtoHH;
break;
case 2:
pref.m_SyncType = eHHtoPC;
break;
case 3:*/
default:
pref.m_SyncType = eDoNothing;
break;
}
pref.m_SyncPref = (actDlg.m_bMakeDefault) ? ePermanentPreference : eTemporaryPreference;
nRtn = 0;
}
return nRtn;
}
La fonction qui est appelée lorsque tu demandes à configurer la conduite depuis le programme hotsync. En général, tu affiches le dialogue de choix entre synchronise / Palm remplace PC / ... Les exemples de dialogue dans le CDK sont assez simples, il me semble...
CODE
/////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////
//
// Method: CfgConduit
//
// Description: This is the second instance of ConfigureConduit. This function
// is provided with more info from the caller.
// This version of the function only supports the eConfig1 enum.
//
// Parameters: ConduitCfgEnum cfgType - enum specifying the version of the
// CfgConduit Call.
// void *pArgs - In the eConfig1 call, this is a pointer to aCfgConduitInfoType
// structure. This structure provides extra info to the conduit.
// DWORD *pdwArgsSize - This is a pointer to a DWORD specifying the size of pArgs.
//
// Returns: 0 - Success.
// !0 - error code.
//
/////////////////////////////////////////////////////////////////////////////
// REVISION HISTORY:
// 01/23/98 KRM Created
//
/////////////////////////////////////////////////////////////////////////////
ExportFunc long CfgConduit(ConduitCfgEnum cfgType, void * pArgs, DWORD * pdwArgsSize)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
long nRtn = -1;
TCHAR szName[256];
DWORD dwNamesize;
CMCConfigureDlg actDlg;
ConduitRequestInfoType infoStruct;
CfgConduitInfoType * pCfgInfo;
dwNamesize = sizeof(szName);
if (cfgType != eConfig1)
{
return CONDERR_UNSUPPORTED_CFGCONDUIT_ENUM;
}
if (!pArgs)
{
return CONDERR_INVALID_INARGS_PTR;
}
if (!pdwArgsSize)
{
return CONDERR_INVALID_ARGSSIZE_PTR;
}
if (*pdwArgsSize != SZ_CFGCONDUITINFO)
{
return CONDERR_INVALID_ARGSSIZE;
}
pCfgInfo = (CfgConduitInfoType *)pArgs;
if (pCfgInfo->dwVersion != CFGCONDUITINFO_VERSION_1)
{
return CONDERR_UNSUPPORTED_STRUCT_VERSION;
}
infoStruct.dwVersion = CONDUITREQUESTINFO_VERSION_1;
infoStruct.dwSize = SZ_CONDUITREQUESTINFO;
infoStruct.dwCreatorId = pCfgInfo -> dwCreatorId;
infoStruct.dwUserId = pCfgInfo -> dwUserId;
strcpy(infoStruct.szUser, pCfgInfo -> szUser);
nRtn = GetConduitInfo(eConduitName, (void *) &infoStruct, (void *) szName, &dwNamesize);
if (nRtn)
{
return nRtn;
}
actDlg.m_csGroupText = szName;
switch (pCfgInfo->syncTemporary)
{
case eFast:
case eSlow:
actDlg.m_nActionIndex = 0;
break;
/* case ePCtoHH:
actDlg.m_nActionIndex = 1;
break;
case eHHtoPC:
actDlg.m_nActionIndex = 2;
break;*/
case eDoNothing:
default:
actDlg.m_nActionIndex = 1;
break;
}
nRtn = -1;
if (actDlg.DoModal() == IDOK)
{
switch (actDlg.m_nActionIndex)
{
case 0:
pCfgInfo->syncNew = eFast;
break;
case 1:
/* pCfgInfo->syncNew = ePCtoHH;
break;
case 2:
pCfgInfo->syncNew = eHHtoPC;
break;
case 3:*/
default:
pCfgInfo->syncNew = eDoNothing;
break;
}
pCfgInfo->syncPref = (actDlg.m_bMakeDefault) ? ePermanentPreference : eTemporaryPreference;
nRtn = 0;
}
return nRtn;
}
La même (

) mais pour une version plus ancienne de hotsync...